#include <iostream>
#include <iomanip>
#include <chrono>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
#include <stdarg.h>
#include <random>
#include <ctime>
#include <bitset>
#include <immintrin.h> //simd
#include <format>	   // g++编译时添加 -std=c++20   MSVC编译器也需指定c++20
long long int getcycle()
{
	uint64_t low, high;
	__asm volatile("rdtsc" : "=a"(low), "=d"(high));
	return (high << 32) | low;
}
static const unsigned long long powers_ten[687] = {0xbf29dcaba82fdeae, 0xeef453d6923bd65a, 0x9558b4661b6565f8, 0xbaaee17fa23ebf76, 0xe95a99df8ace6f54, 0x91d8a02bb6c10594, 0xb64ec836a47146fa, 0xe3e27a444d8d98b8, 0x8e6d8c6ab0787f73, 0xb208ef855c969f50, 0xde8b2b66b3bc4724, 0x8b16fb203055ac76, 0xaddcb9e83c6b1794, 0xd953e8624b85dd79, 0x87d4713d6f33aa6c, 0xa9c98d8ccb009506, 0xd43bf0effdc0ba48, 0x84a57695fe98746d, 0xa5ced43b7e3e9188, 0xcf42894a5dce35ea, 0x818995ce7aa0e1b2, 0xa1ebfb4219491a1f, 0xca66fa129f9b60a7, 0xfd00b897478238d1, 0x9e20735e8cb16382, 0xc5a890362fddbc63, 0xf712b443bbd52b7c, 0x9a6bb0aa55653b2d, 0xc1069cd4eabe89f9, 0xf148440a256e2c77, 0x96cd2a865764dbca, 0xbc807527ed3e12bd, 0xeba09271e88d976c, 0x93445b8731587ea3, 0xb8157268fdae9e4c, 0xe61acf033d1a45df, 0x8fd0c16206306bac, 0xb3c4f1ba87bc8697, 0xe0b62e2929aba83c, 0x8c71dcd9ba0b4926, 0xaf8e5410288e1b6f, 0xdb71e91432b1a24b, 0x892731ac9faf056f, 0xab70fe17c79ac6ca, 0xd64d3d9db981787d, 0x85f0468293f0eb4e, 0xa76c582338ed2622, 0xd1476e2c07286faa, 0x82cca4db847945ca, 0xa37fce126597973d, 0xcc5fc196fefd7d0c, 0xff77b1fcbebcdc4f, 0x9faacf3df73609b1, 0xc795830d75038c1e, 0xf97ae3d0d2446f25, 0x9becce62836ac577, 0xc2e801fb244576d5, 0xf3a20279ed56d48a, 0x9845418c345644d7, 0xbe5691ef416bd60c, 0xedec366b11c6cb8f, 0x94b3a202eb1c3f39, 0xb9e08a83a5e34f08, 0xe858ad248f5c22ca, 0x91376c36d99995be, 0xb58547448ffffb2e, 0xe2e69915b3fff9f9, 0x8dd01fad907ffc3c, 0xb1442798f49ffb4b, 0xdd95317f31c7fa1d, 0x8a7d3eef7f1cfc52, 0xad1c8eab5ee43b67, 0xd863b256369d4a41, 0x873e4f75e2224e68, 0xa90de3535aaae202, 0xd3515c2831559a83, 0x8412d9991ed58092, 0xa5178fff668ae0b6, 0xce5d73ff402d98e4, 0x80fa687f881c7f8e, 0xa139029f6a239f72, 0xc987434744ac874f, 0xfbe9141915d7a922, 0x9d71ac8fada6c9b5, 0xc4ce17b399107c23, 0xf6019da07f549b2b, 0x99c102844f94e0fb, 0xc0314325637a193a, 0xf03d93eebc589f88, 0x96267c7535b763b5, 0xbbb01b9283253ca3, 0xea9c227723ee8bcb, 0x92a1958a7675175f, 0xb749faed14125d37, 0xe51c79a85916f485, 0x8f31cc0937ae58d3, 0xb2fe3f0b8599ef08, 0xdfbdcece67006ac9, 0x8bd6a141006042be, 0xaecc49914078536d, 0xda7f5bf590966849, 0x888f99797a5e012d, 0xaab37fd7d8f58179, 0xd5605fcdcf32e1d7, 0x855c3be0a17fcd26, 0xa6b34ad8c9dfc070, 0xd0601d8efc57b08c, 0x823c12795db6ce57, 0xa2cb1717b52481ed, 0xcb7ddcdda26da269, 0xfe5d54150b090b03, 0x9efa548d26e5a6e2, 0xc6b8e9b0709f109a, 0xf867241c8cc6d4c1, 0x9b407691d7fc44f8, 0xc21094364dfb5637, 0xf294b943e17a2bc4, 0x979cf3ca6cec5b5b, 0xbd8430bd08277231, 0xece53cec4a314ebe, 0x940f4613ae5ed137, 0xb913179899f68584, 0xe757dd7ec07426e5, 0x9096ea6f3848984f, 0xb4bca50b065abe63, 0xe1ebce4dc7f16dfc, 0x8d3360f09cf6e4bd, 0xb080392cc4349ded, 0xdca04777f541c568, 0x89e42caaf9491b61, 0xac5d37d5b79b6239, 0xd77485cb25823ac7, 0x86a8d39ef77164bd, 0xa8530886b54dbdec, 0xd267caa862a12d67, 0x8380dea93da4bc60, 0xa46116538d0deb78, 0xcd795be870516656, 0x806bd9714632dff6, 0xa086cfcd97bf97f4, 0xc8a883c0fdaf7df0, 0xfad2a4b13d1b5d6c, 0x9cc3a6eec6311a64, 0xc3f490aa77bd60fd, 0xf4f1b4d515acb93c, 0x991711052d8bf3c5, 0xbf5cd54678eef0b7, 0xef340a98172aace5, 0x9580869f0e7aac0f, 0xbae0a846d2195713, 0xe998d258869facd7, 0x91ff83775423cc06, 0xb67f6455292cbf08, 0xe41f3d6a7377eeca, 0x8e938662882af53e, 0xb23867fb2a35b28e, 0xdec681f9f4c31f31, 0x8b3c113c38f9f37f, 0xae0b158b4738705f, 0xd98ddaee19068c76, 0x87f8a8d4cfa417ca, 0xa9f6d30a038d1dbc, 0xd47487cc8470652b, 0x84c8d4dfd2c63f3b, 0xa5fb0a17c777cf0a, 0xcf79cc9db955c2cc, 0x81ac1fe293d599c0, 0xa21727db38cb0030, 0xca9cf1d206fdc03c, 0xfd442e4688bd304b, 0x9e4a9cec15763e2f, 0xc5dd44271ad3cdba, 0xf7549530e188c129, 0x9a94dd3e8cf578ba, 0xc13a148e3032d6e8, 0xf18899b1bc3f8ca2, 0x96f5600f15a7b7e5, 0xbcb2b812db11a5de, 0xebdf661791d60f56, 0x936b9fcebb25c996, 0xb84687c269ef3bfb, 0xe65829b3046b0afa, 0x8ff71a0fe2c2e6dc, 0xb3f4e093db73a093, 0xe0f218b8d25088b8, 0x8c974f7383725573, 0xafbd2350644eead0, 0xdbac6c247d62a584, 0x894bc396ce5da772, 0xab9eb47c81f5114f, 0xd686619ba27255a3, 0x8613fd0145877586, 0xa798fc4196e952e7, 0xd17f3b51fca3a7a1, 0x82ef85133de648c5, 0xa3ab66580d5fdaf6, 0xcc963fee10b7d1b3, 0xffbbcfe994e5c620, 0x9fd561f1fd0f9bd4, 0xc7caba6e7c5382c9, 0xf9bd690a1b68637b, 0x9c1661a651213e2d, 0xc31bfa0fe5698db8, 0xf3e2f893dec3f126, 0x986ddb5c6b3a76b8, 0xbe89523386091466, 0xee2ba6c0678b597f, 0x94db483840b717f0, 0xba121a4650e4ddec, 0xe896a0d7e51e1566, 0x915e2486ef32cd60, 0xb5b5ada8aaff80b8, 0xe3231912d5bf60e6, 0x8df5efabc5979c90, 0xb1736b96b6fd83b4, 0xddd0467c64bce4a1, 0x8aa22c0dbef60ee4, 0xad4ab7112eb3929e, 0xd89d64d57a607745, 0x87625f056c7c4a8b, 0xa93af6c6c79b5d2e, 0xd389b47879823479, 0x843610cb4bf160cc, 0xa54394fe1eedb8ff, 0xce947a3da6a9273e, 0x811ccc668829b887, 0xa163ff802a3426a9, 0xc9bcff6034c13053, 0xfc2c3f3841f17c68, 0x9d9ba7832936edc1, 0xc5029163f384a931, 0xf64335bcf065d37d, 0x99ea0196163fa42e, 0xc06481fb9bcf8d3a, 0xf07da27a82c37088, 0x964e858c91ba2655, 0xbbe226efb628afeb, 0xeadab0aba3b2dbe5, 0x92c8ae6b464fc96f, 0xb77ada0617e3bbcb, 0xe55990879ddcaabe, 0x8f57fa54c2a9eab7, 0xb32df8e9f3546564, 0xdff9772470297ebd, 0x8bfbea76c619ef36, 0xaefae51477a06b04, 0xdab99e59958885c5, 0x88b402f7fd75539b, 0xaae103b5fcd2a882, 0xd59944a37c0752a2, 0x857fcae62d8493a5, 0xa6dfbd9fb8e5b88f, 0xd097ad07a71f26b2, 0x825ecc24c8737830, 0xa2f67f2dfa90563b, 0xcbb41ef979346bca, 0xfea126b7d78186bd, 0x9f24b832e6b0f436, 0xc6ede63fa05d3144, 0xf8a95fcf88747d94, 0x9b69dbe1b548ce7d, 0xc24452da229b021c, 0xf2d56790ab41c2a3, 0x97c560ba6b0919a6, 0xbdb6b8e905cb600f, 0xed246723473e3813, 0x9436c0760c86e30c, 0xb94470938fa89bcf, 0xe7958cb87392c2c3, 0x90bd77f3483bb9ba, 0xb4ecd5f01a4aa828, 0xe2280b6c20dd5232, 0x8d590723948a535f, 0xb0af48ec79ace837, 0xdcdb1b2798182245, 0x8a08f0f8bf0f156b, 0xac8b2d36eed2dac6, 0xd7adf884aa879177, 0x86ccbb52ea94baeb, 0xa87fea27a539e9a5, 0xd29fe4b18e88640f, 0x83a3eeeef9153e89, 0xa48ceaaab75a8e2b, 0xcdb02555653131b6, 0x808e17555f3ebf12, 0xa0b19d2ab70e6ed6, 0xc8de047564d20a8c, 0xfb158592be068d2f, 0x9ced737bb6c4183d, 0xc428d05aa4751e4d, 0xf53304714d9265e0, 0x993fe2c6d07b7fac, 0xbf8fdb78849a5f97, 0xef73d256a5c0f77d, 0x95a8637627989aae, 0xbb127c53b17ec159, 0xe9d71b689dde71b0, 0x9226712162ab070e, 0xb6b00d69bb55c8d1, 0xe45c10c42a2b3b06, 0x8eb98a7a9a5b04e3, 0xb267ed1940f1c61c, 0xdf01e85f912e37a3, 0x8b61313bbabce2c6, 0xae397d8aa96c1b78, 0xd9c7dced53c72256, 0x881cea14545c7575, 0xaa242499697392d3, 0xd4ad2dbfc3d07788, 0x84ec3c97da624ab5, 0xa6274bbdd0fadd62, 0xcfb11ead453994ba, 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3e, 0xfd87b5f28300ca0e, 0x9e74d1b791e07e48, 0xc612062576589ddb, 0xf79687aed3eec551, 0x9abe14cd44753b53, 0xc16d9a0095928a27, 0xf1c90080baf72cb1, 0x971da05074da7bef, 0xbce5086492111aeb, 0xec1e4a7db69561a5, 0x9392ee8e921d5d07, 0xb877aa3236a4b449, 0xe69594bec44de15b, 0x901d7cf73ab0acd9, 0xb424dc35095cd80f, 0xe12e13424bb40e13, 0x8cbccc096f5088cc, 0xafebff0bcb24aaff, 0xdbe6fecebdedd5bf, 0x89705f4136b4a597, 0xabcc77118461cefd, 0xd6bf94d5e57a42bc, 0x8637bd05af6c69b6, 0xa7c5ac471b478423, 0xd1b71758e219652c, 0x83126e978d4fdf3b, 0xa3d70a3d70a3d70a, 0xcccccccccccccccd, 0x8000000000000000, 0xa000000000000000, 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000, 0xc350000000000000, 0xf424000000000000, 0x9896800000000000, 0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000, 0xba43b74000000000, 0xe8d4a51000000000, 0x9184e72a00000000, 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000, 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000, 0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000, 0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0, 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940984, 0xa18f07d736b90be5, 0xc9f2c9cd04674edf, 0xfc6f7c4045812296, 0x9dc5ada82b70b59e, 0xc5371912364ce305, 0xf684df56c3e01bc7, 0x9a130b963a6c115c, 0xc097ce7bc90715b3, 0xf0bdc21abb48db20, 0x96769950b50d88f4, 0xbc143fa4e250eb31, 0xeb194f8e1ae525fd, 0x92efd1b8d0cf37be, 0xb7abc627050305ae, 0xe596b7b0c643c719, 0x8f7e32ce7bea5c70, 0xb35dbf821ae4f38c, 0xe0352f62a19e306f, 0x8c213d9da502de45, 0xaf298d050e4395d7, 0xdaf3f04651d47b4c, 0x88d8762bf324cd10, 0xab0e93b6efee0054, 0xd5d238a4abe98068, 0x85a36366eb71f041, 0xa70c3c40a64e6c52, 0xd0cf4b50cfe20766, 0x82818f1281ed44a0, 0xa321f2d7226895c8, 0xcbea6f8ceb02bb3a, 0xfee50b7025c36a08, 0x9f4f2726179a2245, 0xc722f0ef9d80aad6, 0xf8ebad2b84e0d58c, 0x9b934c3b330c8577, 0xc2781f49ffcfa6d5, 0xf316271c7fc3908b, 0x97edd871cfda3a57, 0xbde94e8e43d0c8ec, 0xed63a231d4c4fb27, 0x945e455f24fb1cf9, 0xb975d6b6ee39e437, 0xe7d34c64a9c85d44, 0x90e40fbeea1d3a4b, 0xb51d13aea4a488dd, 0xe264589a4dcdab15, 0x8d7eb76070a08aed, 0xb0de65388cc8ada8, 0xdd15fe86affad912, 0x8a2dbf142dfcc7ab, 0xacb92ed9397bf996, 0xd7e77a8f87daf7fc, 0x86f0ac99b4e8dafd, 0xa8acd7c0222311bd, 0xd2d80db02aabd62c, 0x83c7088e1aab65db, 0xa4b8cab1a1563f52, 0xcde6fd5e09abcf27, 0x80b05e5ac60b6178, 0xa0dc75f1778e39d6, 0xc913936dd571c84c, 0xfb5878494ace3a5f, 0x9d174b2dcec0e47b, 0xc45d1df942711d9a, 0xf5746577930d6501, 0x9968bf6abbe85f20, 0xbfc2ef456ae276e9, 0xefb3ab16c59b14a3, 0x95d04aee3b80ece6, 0xbb445da9ca61281f, 0xea1575143cf97227, 0x924d692ca61be758, 0xb6e0c377cfa2e12e, 0xe498f455c38b997a, 0x8edf98b59a373fec, 0xb2977ee300c50fe7, 0xdf3d5e9bc0f653e1, 0x8b865b215899f46d, 0xae67f1e9aec07188, 0xda01ee641a708dea, 0x884134fe908658b2, 0xaa51823e34a7eedf, 0xd4e5e2cdc1d1ea96, 0x850fadc09923329e, 0xa6539930bf6bff46, 0xcfe87f7cef46ff17, 0x81f14fae158c5f6e, 0xa26da3999aef774a, 0xcb090c8001ab551c, 0xfdcb4fa002162a63, 0x9e9f11c4014dda7e, 0xc646d63501a1511e, 0xf7d88bc24209a565, 0x9ae757596946075f, 0xc1a12d2fc3978937, 0xf209787bb47d6b85, 0x9745eb4d50ce6333, 0xbd176620a501fc00, 0xec5d3fa8ce427b00, 0x93ba47c980e98ce0, 0xb8a8d9bbe123f018, 0xe6d3102ad96cec1e, 0x9043ea1ac7e41393, 0xb454e4a179dd1877, 0xe16a1dc9d8545e95, 0x8ce2529e2734bb1d, 0xb01ae745b101e9e4, 0xdc21a1171d42645d, 0x899504ae72497eba, 0xabfa45da0edbde69, 0xd6f8d7509292d603, 0x865b86925b9bc5c2, 0xa7f26836f282b733, 0xd1ef0244af2364ff, 0x8335616aed761f1f, 0xa402b9c5a8d3a6e7, 0xcd036837130890a1, 0x802221226be55a65, 0xa02aa96b06deb0fe, 0xc83553c5c8965d3d, 0xfa42a8b73abbf48d, 0x9c69a97284b578d8, 0xc38413cf25e2d70e, 0xf46518c2ef5b8cd1, 0x98bf2f79d5993803, 0xbeeefb584aff8604, 0xeeaaba2e5dbf6785, 0x952ab45cfa97a0b3, 0xba756174393d88e0, 0xe912b9d1478ceb17, 0x91abb422ccb812ef, 0xb616a12b7fe617aa, 0xe39c49765fdf9d95, 0x8e41ade9fbebc27d, 0xb1d219647ae6b31c, 0xde469fbd99a05fe3, 0x8aec23d680043bee, 0xada72ccc20054aea, 0xd910f7ff28069da4, 0x87aa9aff79042287, 0xa99541bf57452b28, 0xd3fa922f2d1675f2, 0x847c9b5d7c2e09b7, 0xa59bc234db398c25, 0xcf02b2c21207ef2f, 0x8161afb94b44f57d, 0xa1ba1ba79e1632dc, 0xca28a291859bbf93, 0xfcb2cb35e702af78, 0x9defbf01b061adab, 0xc56baec21c7a1916, 0xf6c69a72a3989f5c, 0x9a3c2087a63f6399, 0xc0cb28a98fcf3c80, 0xf0fdf2d3f3c30b9f, 0x969eb7c47859e744, 0xbc4665b596706115, 0xeb57ff22fc0c795a, 0x9316ff75dd87cbd8, 0xb7dcbf5354e9bece, 0xe5d3ef282a242e82, 0x8fa475791a569d11, 0xb38d92d760ec4455, 0xe070f78d3927556b, 0x8c469ab843b89563, 0xaf58416654a6babb, 0xdb2e51bfe9d0696a, 0x88fcf317f22241e2, 0xab3c2fddeeaad25b, 0xd60b3bd56a5586f2, 0x85c7056562757457, 0xa738c6bebb12d16d, 0xd106f86e69d785c8, 0x82a45b450226b39d, 0xa34d721642b06084, 0xcc20ce9bd35c78a5, 0xff290242c83396ce, 0x9f79a169bd203e41, 0xc75809c42c684dd1, 0xf92e0c3537826146, 0x9bbcc7a142b17ccc, 0xc2abf989935ddbfe, 0xf356f7ebf83552fe, 0x98165af37b2153df, 0xbe1bf1b059e9a8d6, 0xeda2ee1c7064130c, 0x9485d4d1c63e8be8, 0xb9a74a0637ce2ee1, 0xe8111c87c5c1ba9a, 0x910ab1d4db9914a0, 0xb54d5e4a127f59c8, 0xe2a0b5dc971f303a, 0x8da471a9de737e24, 0xb10d8e1456105dad, 0xdd50f1996b947519, 0x8a5296ffe33cc930, 0xace73cbfdc0bfb7b, 0xd8210befd30efa5a, 0x8714a775e3e95c78, 0xa8d9d1535ce3b396, 0xd31045a8341ca07c, 0x83ea2b892091e44e, 0xa4e4b66b68b65d61, 0xce1de40642e3f4b9, 0x80d2ae83e9ce78f4, 0xa1075a24e4421731, 0xc94930ae1d529cfd, 0xfb9b7cd9a4a7443c, 0x9d412e0806e88aa6, 0xc491798a08a2ad4f, 0xf5b5d7ec8acb58a3, 0x9991a6f3d6bf1766, 0xbff610b0cc6edd3f, 0xeff394dcff8a948f, 0x95f83d0a1fb69cd9, 0xbb764c4ca7a44410, 0xea53df5fd18d5514, 0x92746b9be2f8552c, 0xb7118682dbb66a77, 0xe4d5e82392a40515, 0x8f05b1163ba6832d, 0xb2c71d5bca9023f8, 0xdf78e4b2bd342cf7, 0x8bab8eefb6409c1a, 0xae9672aba3d0c321, 0xda3c0f568cc4f3e9, 0x8865899617fb1871, 0xaa7eebfb9df9de8e, 0xd51ea6fa85785631, 0x8533285c936b35df, 0xa67ff273b8460357, 0xd01fef10a657842c, 0x8213f56a67f6b29c, 0xa298f2c501f45f43, 0xcb3f2f7642717713, 0xfe0efb53d30dd4d8, 0x9ec95d1463e8a507, 0xc67bb4597ce2ce49, 0xf81aa16fdc1b81db, 0x9b10a4e5e9913129, 0xc1d4ce1f63f57d73, 0xf24a01a73cf2dcd0, 0x976e41088617ca02, 0xbd49d14aa79dbc82, 0xec9c459d51852ba3, 0x93e1ab8252f33b46, 0xb8da1662e7b00a17, 0xe7109bfba19c0c9d, 0x906a617d450187e2, 0xb484f9dc9641e9db, 0xe1a63853bbd26451, 0x8d07e33455637eb3, 0xb049dc016abc5e60, 0xdc5c5301c56b75f7, 0x89b9b3e11b6329bb, 0xac2820d9623bf429, 0xd732290fbacaf134, 0x867f59a9d4bed6c0, 0xa81f301449ee8c70, 0xd226fc195c6a2f8c, 0x83585d8fd9c25db8, 0xa42e74f3d032f526, 0xcd3a1230c43fb26f, 0x80444b5e7aa7cf85, 0xa0555e361951c367, 0xc86ab5c39fa63441, 0xfa856334878fc151, 0x9c935e00d4b9d8d2, 0xc3b8358109e84f07, 0xf4a642e14c6262c9, 0x98e7e9cccfbd7dbe, 0xbf21e44003acdd2d, 0xeeea5d5004981478, 0x95527a5202df0ccb, 0xbaa718e68396cffe, 0xe950df20247c83fd, 0x91d28b7416cdd27e, 0xb6472e511c81471e, 0xe3d8f9e563a198e5, 0x8e679c2f5e44ff8f, 0xb201833b35d63f73, 0xde81e40a034bcf50, 0x8b112e86420f6192, 0xadd57a27d29339f6, 0xd94ad8b1c7380874, 0x87cec76f1c830549, 0xa9c2794ae3a3c69b, 0xd433179d9c8cb841, 0x849feec281d7f329, 0xa5c7ea73224deff3, 0xcf39e50feae16bf0, 0x81842f29f2cce376, 0xa1e53af46f801c53, 0xca5e89b18b602368, 0xfcf62c1dee382c42, 0x9e19db92b4e31ba9, 0xc5a05277621be294, 0xf70867153aa2db39, 0x9a65406d44a5c903, 0xc0fe908895cf3b44, 0xf13e34aabb430a15, 0x96c6e0eab509e64d, 0xbc789925624c5fe1, 0xeb96bf6ebadf77d9, 0x933e37a534cbaae8, 0xb80dc58e81fe95a1, 0xe61136f2227e3b0a, 0x8fcac257558ee4e6, 0xb3bd72ed2af29e20, 0xe0accfa875af45a8, 0x8c6c01c9498d8b89, 0xaf87023b9bf0ee6b, 0xdb68c2ca82ed2a06, 0x892179be91d43a44, 0xab69d82e364948d4};

static const long long int powers_ten_e[687] = {-1203, -1200, -1196, -1193, -1190, -1186, -1183, -1180, -1176, -1173, -1170, -1166, -1163, -1160, -1156, -1153, -1150, -1146, -1143, -1140, -1136, -1133, -1130, -1127, -1123, -1120, -1117, -1113, -1110, -1107, -1103, -1100, -1097, -1093, -1090, -1087, -1083, -1080, -1077, -1073, -1070, -1067, -1063, -1060, -1057, -1053, -1050, -1047, -1043, -1040, -1037, -1034, -1030, -1027, -1024, -1020, -1017, -1014, -1010, -1007, -1004, -1000, -997, -994, -990, -987, -984, -980, -977, -974, -970, -967, -964, -960, -957, -954, -950, -947, -944, -940, -937, -934, -931, -927, -924, -921, -917, -914, -911, -907, -904, -901, -897, -894, -891, -887, -884, -881, -877, -874, -871, -867, -864, -861, -857, -854, -851, -847, -844, -841, -838, -834, -831, -828, -824, -821, -818, -814, -811, -808, -804, -801, -798, -794, -791, -788, -784, -781, -778, -774, -771, -768, -764, -761, -758, -754, -751, -748, -744, -741, -738, -735, -731, -728, -725, -721, -718, -715, -711, -708, -705, -701, -698, -695, -691, -688, -685, -681, -678, -675, -671, -668, -665, -661, -658, -655, -651, -648, -645, -642, -638, -635, -632, -628, -625, -622, -618, -615, -612, -608, -605, -602, -598, -595, -592, -588, -585, -582, -578, -575, -572, -568, -565, -562, -558, -555, -552, -549, -545, -542, -539, -535, -532, -529, -525, -522, -519, -515, -512, -509, -505, -502, -499, -495, -492, -489, -485, -482, -479, -475, -472, -469, -465, -462, -459, -455, -452, -449, -446, -442, -439, -436, -432, -429, -426, -422, -419, -416, -412, -409, -406, -402, -399, -396, -392, -389, -386, -382, -379, -376, -372, -369, -366, -362, -359, -356, -353, -349, -346, -343, -339, -336, -333, -329, -326, -323, -319, -316, -313, -309, -306, -303, -299, -296, -293, -289, -286, -283, -279, -276, -273, -269, -266, -263, -259, -256, -253, -250, -246, -243, -240, -236, -233, -230, -226, -223, -220, -216, -213, -210, -206, -203, -200, -196, -193, -190, -186, -183, -180, -176, -173, -170, -166, -163, -160, -157, -153, -150, -147, -143, -140, -137, -133, -130, -127, -123, -120, -117, -113, -110, -107, -103, -100, -97, -93, -90, -87, -83, -80, -77, -73, -70, -67, -63, -60, -57, -54, -50, -47, -44, -40, -37, -34, -30, -27, -24, -20, -17, -14, -10, -7, -4, 0, 3, 6, 10, 13, 16, 20, 23, 26, 30, 33, 36, 39, 43, 46, 49, 53, 56, 59, 63, 66, 69, 73, 76, 79, 83, 86, 89, 93, 96, 99, 103, 106, 109, 113, 116, 119, 123, 126, 129, 132, 136, 139, 142, 146, 149, 152, 156, 159, 162, 166, 169, 172, 176, 179, 182, 186, 189, 192, 196, 199, 202, 206, 209, 212, 216, 219, 222, 226, 229, 232, 235, 239, 242, 245, 249, 252, 255, 259, 262, 265, 269, 272, 275, 279, 282, 285, 289, 292, 295, 299, 302, 305, 309, 312, 315, 319, 322, 325, 328, 332, 335, 338, 342, 345, 348, 352, 355, 358, 362, 365, 368, 372, 375, 378, 382, 385, 388, 392, 395, 398, 402, 405, 408, 412, 415, 418, 422, 425, 428, 431, 435, 438, 441, 445, 448, 451, 455, 458, 461, 465, 468, 471, 475, 478, 481, 485, 488, 491, 495, 498, 501, 505, 508, 511, 515, 518, 521, 524, 528, 531, 534, 538, 541, 544, 548, 551, 554, 558, 561, 564, 568, 571, 574, 578, 581, 584, 588, 591, 594, 598, 601, 604, 608, 611, 614, 617, 621, 624, 627, 631, 634, 637, 641, 644, 647, 651, 654, 657, 661, 664, 667, 671, 674, 677, 681, 684, 687, 691, 694, 697, 701, 704, 707, 711, 714, 717, 720, 724, 727, 730, 734, 737, 740, 744, 747, 750, 754, 757, 760, 764, 767, 770, 774, 777, 780, 784, 787, 790, 794, 797, 800, 804, 807, 810, 813, 817, 820, 823, 827, 830, 833, 837, 840, 843, 847, 850, 853, 857, 860, 863, 867, 870, 873, 877, 880, 883, 887, 890, 893, 897, 900, 903, 907, 910, 913, 916, 920, 923, 926, 930, 933, 936, 940, 943, 946, 950, 953, 956, 960, 963, 966, 970, 973, 976, 980, 983, 986, 990, 993, 996, 1000, 1003, 1006, 1009, 1013, 1016, 1019, 1023, 1026, 1029, 1033, 1036, 1039, 1043, 1046, 1049, 1053, 1056, 1059, 1063, 1066, 1069, 1073, 1076};
union
{
	// size=8byte
	struct
	{
		int i;
		int j;
	} ll;
	struct
	{
		float i;
		float j;
	} f2;
	double d;
	int64_t i64;
} v;
#define UINT64_C2(h, l) ((static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l))
struct DiyFp
{
	DiyFp() {}
	DiyFp(uint64_t f, int e) : f(f), e(e) {}
	DiyFp(double d)
	{
		uint64_t u64 = *(uint64_t *)&d;
		int biased_e = (u64 & kDpExponentMask) >> kDpSignificandSize;
		uint64_t significand = (u64 & kDpSignificandMask);
		if (biased_e != 0)
		{
			f = significand + kDpHiddenBit;
			e = biased_e - kDpExponentBias; // 1075
		}
		else
		{
			f = significand;
			e = kDpMinExponent + 1;
		}
	}
	void normalize(int i)
	{
		f <<= i; //
		e -= i;
	}
	DiyFp operator*(const DiyFp &rhs) const
	{
		const uint64_t M32 = 0xFFFFFFFF;
		const uint64_t a = f >> 32;
		const uint64_t b = f & M32;
		const uint64_t c = rhs.f >> 32;
		const uint64_t d = rhs.f & M32;
		const uint64_t ac = a * c;
		const uint64_t bc = b * c;
		const uint64_t ad = a * d;
		const uint64_t bd = b * d;
		uint64_t hi = ac + (ad >> 32) + (bc >> 32);
		uint64_t lo = bd + (ad & M32) + (bc & M32);
		return DiyFp(hi + (lo >> 63), e + rhs.e + 64);
	}
	static const int kDiySignificandSize = 64;
	static const int kDpSignificandSize = 52;
	static const int kDpExponentBias = 0x3FF + kDpSignificandSize; // 1023+52=1075
	static const int kDpMinExponent = -kDpExponentBias;			   //-1075
	static const uint64_t kDpExponentMask = UINT64_C2(0x7FF00000, 0x00000000);
	static const uint64_t kDpSignificandMask = UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
	static const uint64_t kDpHiddenBit = UINT64_C2(0x00100000, 0x00000000); // 1<<52
	uint64_t f;
	int e;
};
int64_t array[2046] = {22250738585072014, 44501477170144028, 89002954340288055, 17800590868057611, 35601181736115222, 71202363472230444, 14240472694446089, 28480945388892178, 56961890777784355, 11392378155556871, 22784756311113742, 45569512622227484, 91139025244454969, 18227805048890994, 36455610097781987, 72911220195563975, 14582244039112795, 29164488078225590, 58328976156451180, 11665795231290236, 23331590462580472, 46663180925160944, 93326361850321888, 18665272370064378, 37330544740128755, 74661089480257510, 14932217896051502, 29864435792103004, 59728871584206008, 11945774316841202, 23891548633682403, 47783097267364807, 95566194534729613, 19113238906945923, 38226477813891845, 76452955627783691, 15290591125556738, 30581182251113476, 61162364502226952, 12232472900445390, 24464945800890781, 48929891601781562, 97859783203563124, 19571956640712625, 39143913281425250, 78287826562850499, 15657565312570100, 31315130625140200, 62630261250280399, 12526052250056080, 25052104500112160, 50104209000224319, 10020841800044864, 20041683600089728, 40083367200179456, 80166734400358911, 16033346880071782, 32066693760143564, 64133387520287129, 12826677504057426, 25653355008114852, 51306710016229703, 10261342003245941, 20522684006491881, 41045368012983762, 82090736025967525, 16418147205193505, 32836294410387010, 65672588820774020, 13134517764154804, 26269035528309608, 52538071056619216, 10507614211323843, 21015228422647686, 42030456845295373, 84060913690590746, 16812182738118149, 33624365476236298, 67248730952472596, 13449746190494519, 26899492380989039, 53798984761978077, 10759796952395615, 21519593904791231, 43039187809582462, 86078375619164923, 17215675123832985, 34431350247665969, 68862700495331939, 13772540099066388, 27545080198132776, 55090160396265551, 11018032079253110, 22036064158506220, 44072128317012441, 88144256634024882, 17628851326804976, 35257702653609953, 70515405307219905, 14103081061443981, 28206162122887962, 56412324245775924, 11282464849155185, 22564929698310370, 45129859396620739, 90259718793241479, 18051943758648296, 36103887517296592, 72207775034593183, 14441555006918637, 28883110013837273, 57766220027674546, 11553244005534909, 23106488011069819, 46212976022139637, 92425952044279274, 18485190408855855, 36970380817711710, 73940761635423419, 14788152327084684, 29576304654169368, 59152609308338736, 11830521861667747, 23661043723335494, 47322087446670988, 94644174893341977, 18928834978668395, 37857669957336791, 75715339914673582, 15143067982934716, 30286135965869433, 60572271931738865, 12114454386347773, 24228908772695546, 48457817545391092, 96915635090782184, 19383127018156437, 38766254036312874, 77532508072625747, 15506501614525149, 31013003229050299, 62026006458100598, 12405201291620120, 24810402583240239, 49620805166480478, 99241610332960957, 19848322066592191, 39696644133184383, 79393288266368765, 15878657653273753, 31757315306547506, 63514630613095012, 12702926122619002, 25405852245238005, 50811704490476010, 10162340898095202, 20324681796190404, 40649363592380808, 81298727184761616, 16259745436952323, 32519490873904646, 65038981747809293, 13007796349561859, 26015592699123717, 52031185398247434, 10406237079649487, 20812474159298974, 41624948318597947, 83249896637195895, 16649979327439179, 33299958654878358, 66599917309756716, 13319983461951343, 26639966923902686, 53279933847805373, 10655986769561075, 21311973539122149, 42623947078244298, 85247894156488596, 17049578831297719, 34099157662595438, 68198315325190877, 13639663065038175, 27279326130076351, 54558652260152701, 10911730452030540, 21823460904061081, 43646921808122161, 87293843616244322, 17458768723248864, 34917537446497729, 69835074892995458, 13967014978599092, 27934029957198183, 55868059914396366, 11173611982879273, 22347223965758547, 44694447931517093, 89388895863034186, 17877779172606837, 35755558345213674, 71511116690427349, 14302223338085470, 28604446676170940, 57208893352341879, 11441778670468376, 22883557340936752, 45767114681873503, 91534229363747007, 18306845872749401, 36613691745498803, 73227383490997605, 14645476698199521, 29290953396399042, 58581906792798084, 11716381358559617, 23432762717119234, 46865525434238467, 93731050868476935, 18746210173695387, 37492420347390774, 74984840694781548, 14996968138956310, 29993936277912619, 59987872555825238, 11997574511165048, 23995149022330095, 47990298044660191, 95980596089320381, 19196119217864076, 38392238435728152, 76784476871456305, 15356895374291261, 30713790748582522, 61427581497165044, 12285516299433009, 24571032598866018, 49142065197732035, 98284130395464070, 19656826079092814, 39313652158185628, 78627304316371256, 15725460863274251, 31450921726548502, 62901843453097005, 12580368690619401, 25160737381238802, 50321474762477604, 10064294952495521, 20128589904991042, 40257179809982083, 80514359619964166, 16102871923992833, 32205743847985667, 64411487695971333, 12882297539194267, 25764595078388533, 51529190156777066, 10305838031355413, 20611676062710827, 41223352125421653, 82446704250843306, 16489340850168661, 32978681700337323, 65957363400674645, 13191472680134929, 26382945360269858, 52765890720539716, 10553178144107943, 21106356288215886, 42212712576431773, 84425425152863546, 16885085030572709, 33770170061145418, 67540340122290837, 13508068024458167, 27016136048916335, 54032272097832669, 10806454419566534, 21612908839133068, 43225817678266135, 86451635356532271, 17290327071306454, 34580654142612908, 69161308285225817, 13832261657045163, 27664523314090327, 55329046628180653, 11065809325636131, 22131618651272261, 44263237302544523, 88526474605089045, 17705294921017809, 35410589842035618, 70821179684071236, 14164235936814247, 28328471873628494, 56656943747256989, 11331388749451398, 22662777498902796, 45325554997805591, 90651109995611182, 18130221999122236, 36260443998244473, 72520887996488946, 14504177599297789, 29008355198595578, 58016710397191157, 11603342079438231, 23206684158876463, 46413368317752925, 92826736635505851, 18565347327101170, 37130694654202340, 74261389308404681, 14852277861680936, 29704555723361872, 59409111446723744, 11881822289344749, 23763644578689498, 47527289157378996, 95054578314757991, 19010915662951598, 38021831325903196, 76043662651806393, 15208732530361279, 30417465060722557, 60834930121445114, 12166986024289023, 24333972048578046, 48667944097156091, 97335888194312183, 19467177638862437, 38934355277724873, 77868710555449746, 15573742111089949, 31147484222179899, 62294968444359797, 12458993688871959, 24917987377743919, 49835974755487838, 99671949510975675, 19934389902195135, 39868779804390270, 79737559608780540, 15947511921756108, 31895023843512216, 63790047687024432, 12758009537404886, 25516019074809773, 51032038149619546, 10206407629923909, 20412815259847818, 40825630519695637, 81651261039391273, 16330252207878255, 32660504415756509, 65321008831513019, 13064201766302604, 26128403532605207, 52256807065210415, 10451361413042083, 20902722826084166, 41805445652168332, 83610891304336664, 16722178260867333, 33444356521734666, 66888713043469331, 13377742608693866, 26755485217387732, 53510970434775465, 10702194086955093, 21404388173910186, 42808776347820372, 85617552695640744, 17123510539128149, 34247021078256297, 68494042156512595, 13698808431302519, 27397616862605038, 54795233725210076, 10959046745042015, 21918093490084030, 43836186980168061, 87672373960336122, 17534474792067224, 35068949584134449, 70137899168268897, 14027579833653779, 28055159667307559, 56110319334615118, 11222063866923024, 22444127733846047, 44888255467692094, 89776510935384189, 17955302187076838, 35910604374153675, 71821208748307351, 14364241749661470, 28728483499322940, 57456966998645881, 11491393399729176, 22982786799458352, 45965573598916705, 91931147197833409, 18386229439566682, 36772458879133364, 73544917758266727, 14708983551653345, 29417967103306691, 58835934206613382, 11767186841322676, 23534373682645353, 47068747365290705, 94137494730581411, 18827498946116282, 37654997892232564, 75309995784465129, 15061999156893026, 30123998313786051, 60247996627572103, 12049599325514421, 24099198651028841, 48198397302057682, 96396794604115365, 19279358920823073, 38558717841646146, 77117435683292292, 15423487136658458, 30846974273316917, 61693948546633833, 12338789709326767, 24677579418653533, 49355158837307067, 98710317674614133, 19742063534922827, 39484127069845653, 78968254139691307, 15793650827938261, 31587301655876523, 63174603311753045, 12634920662350609, 25269841324701218, 50539682649402436, 10107936529880487, 20215873059760975, 40431746119521949, 80863492239043898, 16172698447808780, 32345396895617559, 64690793791235119, 12938158758247024, 25876317516494047, 51752635032988095, 10350527006597619, 20701054013195238, 41402108026390476, 82804216052780952, 16560843210556190, 33121686421112381, 66243372842224761, 13248674568444952, 26497349136889905, 52994698273779809, 10598939654755962, 21197879309511924, 42395758619023847, 84791517238047695, 16958303447609539, 33916606895219078, 67833213790438156, 13566642758087631, 27133285516175262, 54266571032350524, 10853314206470105, 21706628412940210, 43413256825880420, 86826513651760839, 17365302730352168, 34730605460704336, 69461210921408671, 13892242184281734, 27784484368563469, 55568968737126937, 11113793747425387, 22227587494850775, 44455174989701550, 88910349979403099, 17782069995880620, 35564139991761240, 71128279983522479, 14225655996704496, 28451311993408992, 56902623986817984, 11380524797363597, 22761049594727193, 45522099189454387, 91044198378908774, 18208839675781755, 36417679351563509, 72835358703127019, 14567071740625404, 29134143481250808, 58268286962501615, 11653657392500323, 23307314785000646, 46614629570001292, 93229259140002584, 18645851828000517, 37291703656001034, 74583407312002067, 14916681462400413, 29833362924800827, 59666725849601654, 11933345169920331, 23866690339840662, 47733380679681323, 95466761359362646, 19093352271872529, 38186704543745059, 76373409087490117, 15274681817498023, 30549363634996047, 61098727269992094, 12219745453998419, 24439490907996837, 48878981815993675, 97757963631987350, 19551592726397470, 39103185452794940, 78206370905589880, 15641274181117976, 31282548362235952, 62565096724471904, 12513019344894381, 25026038689788762, 50052077379577523, 10010415475915505, 20020830951831009, 40041661903662018, 80083323807324037, 16016664761464807, 32033329522929615, 64066659045859230, 12813331809171846, 25626663618343692, 51253327236687384, 10250665447337477, 20501330894674953, 41002661789349907, 82005323578699814, 16401064715739963, 32802129431479926, 65604258862959851, 13120851772591970, 26241703545183940, 52483407090367881, 10496681418073576, 20993362836147152, 41986725672294305, 83973451344588609, 16794690268917722, 33589380537835444, 67178761075670888, 13435752215134178, 26871504430268355, 53743008860536710, 10748601772107342, 21497203544214684, 42994407088429368, 85988814176858736, 17197762835371747, 34395525670743494, 68791051341486989, 13758210268297398, 27516420536594796, 55032841073189591, 11006568214637918, 22013136429275836, 44026272858551673, 88052545717103346, 17610509143420669, 35221018286841338, 70442036573682677, 14088407314736535, 28176814629473071, 56353629258946141, 11270725851789228, 22541451703578456, 45082903407156913, 90165806814313826, 18033161362862765, 36066322725725530, 72132645451451061, 14426529090290212, 28853058180580424, 57706116361160849, 11541223272232170, 23082446544464339, 46164893088928679, 92329786177857358, 18465957235571472, 36931914471142943, 73863828942285886, 14772765788457177, 29545531576914354, 59091063153828709, 11818212630765742, 23636425261531484, 47272850523062967, 94545701046125934, 18909140209225187, 37818280418450374, 75636560836900748, 15127312167380150, 30254624334760299, 60509248669520598, 12101849733904120, 24203699467808239, 48407398935616478, 96814797871232957, 19362959574246591, 38725919148493183, 77451838296986365, 15490367659397273, 30980735318794546, 61961470637589092, 12392294127517818, 24784588255035637, 49569176510071274, 99138353020142548, 19827670604028510, 39655341208057019, 79310682416114038, 15862136483222808, 31724272966445615, 63448545932891231, 12689709186578246, 25379418373156492, 50758836746312984, 10151767349262597, 20303534698525194, 40607069397050388, 81214138794100775, 16242827758820155, 32485655517640310, 64971311035280620, 12994262207056124, 25988524414112248, 51977048828224496, 10395409765644899, 20790819531289798, 41581639062579597, 83163278125159194, 16632655625031839, 33265311250063677, 66530622500127355, 13306124500025471, 26612249000050942, 53224498000101884, 10644899600020377, 21289799200040754, 42579598400081507, 85159196800163014, 17031839360032603, 34063678720065206, 68127357440130412, 13625471488026082, 27250942976052165, 54501885952104329, 10900377190420866, 21800754380841732, 43601508761683463, 87203017523366927, 17440603504673385, 34881207009346771, 69762414018693541, 13952482803738708, 27904965607477417, 55809931214954833, 11161986242990967, 22323972485981933, 44647944971963866, 89295889943927733, 17859177988785547, 35718355977571093, 71436711955142186, 14287342391028437, 28574684782056875, 57149369564113749, 11429873912822750, 22859747825645500, 45719495651290999, 91438991302581999, 18287798260516400, 36575596521032799, 73151193042065599, 14630238608413120, 29260477216826240, 58520954433652479, 11704190886730496, 23408381773460992, 46816763546921983, 93633527093843967, 18726705418768793, 37453410837537587, 74906821675075173, 14981364335015035, 29962728670030069, 59925457340060139, 11985091468012028, 23970182936024055, 47940365872048111, 95880731744096222, 19176146348819244, 38352292697638489, 76704585395276977, 15340917079055395, 30681834158110791, 61363668316221582, 12272733663244316, 24545467326488633, 49090934652977266, 98181869305954531, 19636373861190906, 39272747722381812, 78545495444763625, 15709099088952725, 31418198177905450, 62836396355810900, 12567279271162180, 25134558542324360, 50269117084648720, 10053823416929744, 20107646833859488, 40215293667718976, 80430587335437952, 16086117467087590, 32172234934175181, 64344469868350361, 12868893973670072, 25737787947340145, 51475575894680289, 10295115178936058, 20590230357872116, 41180460715744231, 82360921431488463, 16472184286297693, 32944368572595385, 65888737145190770, 13177747429038154, 26355494858076308, 52710989716152616, 10542197943230523, 21084395886461046, 42168791772922093, 84337583545844186, 16867516709168837, 33735033418337674, 67470066836675349, 13494013367335070, 26988026734670139, 53976053469340279, 10795210693868056, 21590421387736112, 43180842775472223, 86361685550944446, 17272337110188889, 34544674220377779, 69089348440755557, 13817869688151111, 27635739376302223, 55271478752604446, 11054295750520889, 22108591501041778, 44217183002083556, 88434366004167113, 17686873200833423, 35373746401666845, 70747492803333690, 14149498560666738, 28298997121333476, 56597994242666952, 11319598848533390, 22639197697066781, 45278395394133562, 90556790788267124, 18111358157653425, 36222716315306849, 72445432630613699, 14489086526122740, 28978173052245480, 57956346104490959, 11591269220898192, 23182538441796384, 46365076883592767, 92730153767185535, 18546030753437107, 37092061506874214, 74184123013748428, 14836824602749686, 29673649205499371, 59347298410998742, 11869459682199748, 23738919364399497, 47477838728798994, 94955677457597987, 18991135491519597, 37982270983039195, 75964541966078390, 15192908393215678, 30385816786431356, 60771633572862712, 12154326714572542, 24308653429145085, 48617306858290170, 97234613716580339, 19446922743316068, 38893845486632136, 77787690973264271, 15557538194652854, 31115076389305709, 62230152778611417, 12446030555722283, 24892061111444567, 49784122222889134, 99568244445778267, 19913648889155653, 39827297778311307, 79654595556622614, 15930919111324523, 31861838222649046, 63723676445298091, 12744735289059618, 25489470578119236, 50978941156238473, 10195788231247695, 20391576462495389, 40783152924990778, 81566305849981557, 16313261169996311, 32626522339992623, 65253044679985245, 13050608935997049, 26101217871994098, 52202435743988196, 10440487148797639, 20880974297595278, 41761948595190557, 83523897190381114, 16704779438076223, 33409558876152446, 66819117752304891, 13363823550460978, 26727647100921956, 53455294201843913, 10691058840368783, 21382117680737565, 42764235361475130, 85528470722950261, 17105694144590052, 34211388289180104, 68422776578360209, 13684555315672042, 27369110631344083, 54738221262688167, 10947644252537633, 21895288505075267, 43790577010150533, 87581154020301067, 17516230804060213, 35032461608120427, 70064923216240854, 14012984643248171, 28025969286496341, 56051938572992683, 11210387714598537, 22420775429197073, 44841550858394146, 89683101716788293, 17936620343357659, 35873240686715317, 71746481373430634, 14349296274686127, 28698592549372254, 57397185098744507, 11479437019748901, 22958874039497803, 45917748078995606, 91835496157991212, 18367099231598242, 36734198463196485, 73468396926392969, 14693679385278594, 29387358770557188, 58774717541114375, 11754943508222875, 23509887016445750, 47019774032891500, 94039548065783001, 18807909613156600, 37615819226313200, 75231638452626401, 15046327690525280, 30092655381050560, 60185310762101120, 12037062152420224, 24074124304840448, 48148248609680896, 96296497219361793, 19259299443872359, 38518598887744717, 77037197775489434, 15407439555097887, 30814879110195774, 61629758220391547, 12325951644078309, 24651903288156619, 49303806576313238, 98607613152626476, 19721522630525295, 39443045261050590, 78886090522101181, 15777218104420236, 31554436208840472, 63108872417680944, 12621774483536189, 25243548967072378, 50487097934144756, 10097419586828951, 20194839173657902, 40389678347315804, 80779356694631609, 16155871338926322, 32311742677852644, 64623485355705287, 12924697071141057, 25849394142282115, 51698788284564230, 10339757656912846, 20679515313825692, 41359030627651384, 82718061255302767, 16543612251060553, 33087224502121107, 66174449004242214, 13234889800848443, 26469779601696886, 52939559203393771, 10587911840678754, 21175823681357508, 42351647362715017, 84703294725430034, 16940658945086007, 33881317890172014, 67762635780344027, 13552527156068805, 27105054312137611, 54210108624275222, 10842021724855044, 21684043449710089, 43368086899420177, 86736173798840355, 17347234759768071, 34694469519536142, 69388939039072284, 13877787807814457, 27755575615628914, 55511151231257827, 11102230246251565, 22204460492503131, 44408920985006262, 88817841970012523, 17763568394002505, 35527136788005009, 71054273576010019, 14210854715202004, 28421709430404007, 56843418860808015, 11368683772161603, 22737367544323206, 45474735088646412, 90949470177292824, 18189894035458565, 36379788070917130, 72759576141834259, 14551915228366852, 29103830456733704, 58207660913467407, 11641532182693481, 23283064365386963, 46566128730773926, 93132257461547852, 18626451492309570, 37252902984619141, 74505805969238281, 14901161193847656, 29802322387695312, 59604644775390625, 11920928955078125, 23841857910156250, 47683715820312500, 95367431640625000, 19073486328125000, 38146972656250000, 76293945312500000, 15258789062500000, 30517578125000000, 61035156250000000, 12207031250000000, 24414062500000000, 48828125000000000, 97656250000000000, 19531250000000000, 39062500000000000, 78125000000000000, 15625000000000000, 31250000000000000, 62500000000000000, 12500000000000000, 25000000000000000, 50000000000000000, 10000000000000000, 20000000000000000, 40000000000000000, 80000000000000000, 16000000000000000, 32000000000000000, 64000000000000000, 12800000000000000, 25600000000000000, 51200000000000000, 10240000000000000, 20480000000000000, 40960000000000000, 81920000000000000, 16384000000000000, 32768000000000000, 65536000000000000, 13107200000000000, 26214400000000000, 52428800000000000, 10485760000000000, 20971520000000000, 41943040000000000, 83886080000000000, 16777216000000000, 33554432000000000, 67108864000000000, 13421772800000000, 26843545600000000, 53687091200000000, 10737418240000000, 21474836480000000, 42949672960000000, 85899345920000000, 17179869184000000, 34359738368000000, 68719476736000000, 13743895347200000, 27487790694400000, 54975581388800000, 10995116277760000, 21990232555520000, 43980465111040000, 87960930222080000, 17592186044416000, 35184372088832000, 70368744177664000, 14073748835532800, 28147497671065600, 56294995342131200, 11258999068426240, 22517998136852480, 45035996273704960, 90071992547409920, 18014398509481984, 36028797018963968, 72057594037927936, 14411518807585587, 28823037615171174, 57646075230342349, 11529215046068470, 23058430092136940, 46116860184273879, 92233720368547758, 18446744073709552, 36893488147419103, 73786976294838206, 14757395258967641, 29514790517935283, 59029581035870565, 11805916207174113, 23611832414348226, 47223664828696452, 94447329657392904, 18889465931478581, 37778931862957162, 75557863725914323, 15111572745182865, 30223145490365729, 60446290980731459, 12089258196146292, 24178516392292583, 48357032784585167, 96714065569170334, 19342813113834067, 38685626227668134, 77371252455336267, 15474250491067253, 30948500982134507, 61897001964269014, 12379400392853803, 24758800785707605, 49517601571415211, 99035203142830422, 19807040628566084, 39614081257132169, 79228162514264338, 15845632502852868, 31691265005705735, 63382530011411470, 12676506002282294, 25353012004564588, 50706024009129176, 10141204801825835, 20282409603651670, 40564819207303341, 81129638414606682, 16225927682921336, 32451855365842673, 64903710731685345, 12980742146337069, 25961484292674138, 51922968585348276, 10384593717069655, 20769187434139311, 41538374868278621, 83076749736557242, 16615349947311448, 33230699894622897, 66461399789245794, 13292279957849159, 26584559915698317, 53169119831396635, 10633823966279327, 21267647932558654, 42535295865117308, 85070591730234616, 17014118346046923, 34028236692093846, 68056473384187693, 13611294676837539, 27222589353675077, 54445178707350154, 10889035741470031, 21778071482940062, 43556142965880123, 87112285931760247, 17422457186352049, 34844914372704099, 69689828745408197, 13937965749081639, 27875931498163279, 55751862996326558, 11150372599265312, 22300745198530623, 44601490397061246, 89202980794122493, 17840596158824499, 35681192317648997, 71362384635297994, 14272476927059599, 28544953854119198, 57089907708238395, 11417981541647679, 22835963083295358, 45671926166590716, 91343852333181432, 18268770466636286, 36537540933272573, 73075081866545146, 14615016373309029, 29230032746618058, 58460065493236117, 11692013098647223, 23384026197294447, 46768052394588893, 93536104789177787, 18707220957835557, 37414441915671115, 74828883831342229, 14965776766268446, 29931553532536892, 59863107065073784, 11972621413014757, 23945242826029513, 47890485652059027, 95780971304118054, 19156194260823611, 38312388521647221, 76624777043294443, 15324955408658889, 30649910817317777, 61299821634635554, 12259964326927111, 24519928653854222, 49039857307708443, 98079714615416887, 19615942923083377, 39231885846166755, 78463771692333510, 15692754338466702, 31385508676933404, 62771017353866808, 12554203470773362, 25108406941546723, 50216813883093446, 10043362776618689, 20086725553237378, 40173451106474757, 80346902212949514, 16069380442589903, 32138760885179806, 64277521770359611, 12855504354071922, 25711008708143844, 51422017416287689, 10284403483257538, 20568806966515076, 41137613933030151, 82275227866060302, 16455045573212060, 32910091146424121, 65820182292848242, 13164036458569648, 26328072917139297, 52656145834278593, 10531229166855719, 21062458333711437, 42124916667422875, 84249833334845749, 16849966666969150, 33699933333938300, 67399866667876599, 13479973333575320, 26959946667150640, 53919893334301280, 10783978666860256, 21567957333720512, 43135914667441024, 86271829334882047, 17254365866976409, 34508731733952819, 69017463467905638, 13803492693581128, 27606985387162255, 55213970774324510, 11042794154864902, 22085588309729804, 44171176619459608, 88342353238919216, 17668470647783843, 35336941295567687, 70673882591135373, 14134776518227075, 28269553036454149, 56539106072908299, 11307821214581660, 22615642429163319, 45231284858326639, 90462569716653278, 18092513943330656, 36185027886661311, 72370055773322622, 14474011154664524, 28948022309329049, 57896044618658098, 11579208923731620, 23158417847463239, 46316835694926478, 92633671389852956, 18526734277970591, 37053468555941183, 74106937111882365, 14821387422376473, 29642774844752946, 59285549689505892, 11857109937901178, 23714219875802357, 47428439751604714, 94856879503209427, 18971375900641885, 37942751801283771, 75885503602567542, 15177100720513508, 30354201441027017, 60708402882054033, 12141680576410807, 24283361152821613, 48566722305643227, 97133444611286454, 19426688922257291, 38853377844514581, 77706755689029163, 15541351137805833, 31082702275611665, 62165404551223330, 12433080910244666, 24866161820489332, 49732323640978664, 99464647281957328, 19892929456391466, 39785858912782931, 79571717825565863, 15914343565113173, 31828687130226345, 63657374260452690, 12731474852090538, 25462949704181076, 50925899408362152, 10185179881672430, 20370359763344861, 40740719526689722, 81481439053379443, 16296287810675889, 32592575621351777, 65185151242703555, 13037030248540711, 26074060497081422, 52148120994162844, 10429624198832569, 20859248397665138, 41718496795330275, 83436993590660550, 16687398718132110, 33374797436264220, 66749594872528440, 13349918974505688, 26699837949011376, 53399675898022752, 10679935179604550, 21359870359209101, 42719740718418202, 85439481436836403, 17087896287367281, 34175792574734561, 68351585149469123, 13670317029893825, 27340634059787649, 54681268119575298, 10936253623915060, 21872507247830119, 43745014495660238, 87490028991320477, 17498005798264095, 34996011596528191, 69992023193056382, 13998404638611276, 27996809277222553, 55993618554445105, 11198723710889021, 22397447421778042, 44794894843556084, 89589789687112168, 17917957937422434, 35835915874844867, 71671831749689735, 14334366349937947, 28668732699875894, 57337465399751788, 11467493079950358, 22934986159900715, 45869972319801430, 91739944639602860, 18347988927920572, 36695977855841144, 73391955711682288, 14678391142336458, 29356782284672915, 58713564569345831, 11742712913869166, 23485425827738332, 46970851655476665, 93941703310953329, 18788340662190666, 37576681324381332, 75153362648762663, 15030672529752533, 30061345059505065, 60122690119010131, 12024538023802026, 24049076047604052, 48098152095208105, 96196304190416209, 19239260838083242, 38478521676166484, 76957043352332967, 15391408670466593, 30782817340933187, 61565634681866374, 12313126936373275, 24626253872746550, 49252507745493099, 98505015490986198, 19701003098197240, 39402006196394479, 78804012392788958, 15760802478557792, 31521604957115583, 63043209914231167, 12608641982846233, 25217283965692467, 50434567931384933, 10086913586276987, 20173827172553973, 40347654345107947, 80695308690215893, 16139061738043179, 32278123476086357, 64556246952172715, 12911249390434543, 25822498780869086, 51644997561738172, 10328999512347634, 20657999024695269, 41315998049390537, 82631996098781075, 16526399219756215, 33052798439512430, 66105596879024860, 13221119375804972, 26442238751609944, 52884477503219888, 10576895500643978, 21153791001287955, 42307582002575910, 84615164005151821, 16923032801030364, 33846065602060728, 67692131204121457, 13538426240824291, 27076852481648583, 54153704963297165, 10830740992659433, 21661481985318866, 43322963970637732, 86645927941275464, 17329185588255093, 34658371176510186, 69316742353020371, 13863348470604074, 27726696941208149, 55453393882416297, 11090678776483259, 22181357552966519, 44362715105933038, 88725430211866076, 17745086042373215, 35490172084746430, 70980344169492860, 14196068833898572, 28392137667797144, 56784275335594288, 11356855067118858, 22713710134237715, 45427420268475431, 90854840536950861, 18170968107390172, 36341936214780345, 72683872429560689, 14536774485912138, 29073548971824276, 58147097943648551, 11629419588729710, 23258839177459420, 46517678354918841, 93035356709837682, 18607071341967536, 37214142683935073, 74428285367870146, 14885657073574029, 29771314147148058, 59542628294296116, 11908525658859223, 23817051317718447, 47634102635436893, 95268205270873786, 19053641054174757, 38107282108349515, 76214564216699029, 15242912843339806, 30485825686679612, 60971651373359223, 12194330274671845, 24388660549343689, 48777321098687379, 97554642197374757, 19510928439474951, 39021856878949903, 78043713757899806, 15608742751579961, 31217485503159922, 62434971006319845, 12486994201263969, 24973988402527938, 49947976805055876, 99895953610111751, 19979190722022350, 39958381444044701, 79916762888089401, 15983352577617880, 31966705155235760, 63933410310471521, 12786682062094304, 25573364124188608, 51146728248377217, 10229345649675443, 20458691299350887, 40917382598701773, 81834765197403547, 16366953039480709, 32733906078961419, 65467812157922837, 13093562431584567, 26187124863169135, 52374249726338270, 10474849945267654, 20949699890535308, 41899399781070616, 83798799562141232, 16759759912428246, 33519519824856493, 67039039649712985, 13407807929942597, 26815615859885194, 53631231719770388, 10726246343954078, 21452492687908155, 42904985375816311, 85809970751632621, 17161994150326524, 34323988300653049, 68647976601306097, 13729595320261219, 27459190640522439, 54918381281044878, 10983676256208976, 21967352512417951, 43934705024835902, 87869410049671804, 17573882009934361, 35147764019868722, 70295528039737443, 14059105607947489, 28118211215894977, 56236422431789955, 11247284486357991, 22494568972715982, 44989137945431964, 89978275890863928, 17995655178172786, 35991310356345571, 71982620712691142, 14396524142538228, 28793048285076457, 57586096570152914, 11517219314030583, 23034438628061165, 46068877256122331, 92137754512244662, 18427550902448932, 36855101804897865, 73710203609795730, 14742040721959146, 29484081443918292, 58968162887836584, 11793632577567317, 23587265155134633, 47174530310269267, 94349060620538534, 18869812124107707, 37739624248215414, 75479248496430827, 15095849699286165, 30191699398572331, 60383398797144662, 12076679759428932, 24153359518857865, 48306719037715729, 96613438075431459, 19322687615086292, 38645375230172583, 77290750460345167, 15458150092069033, 30916300184138067, 61832600368276134, 12366520073655227, 24733040147310453, 49466080294620907, 98932160589241814, 19786432117848363, 39572864235696725, 79145728471393451, 15829145694278690, 31658291388557380, 63316582777114761, 12663316555422952, 25326633110845904, 50653266221691809, 10130653244338362, 20261306488676723, 40522612977353447, 81045225954706894, 16209045190941379, 32418090381882757, 64836180763765515, 12967236152753103, 25934472305506206, 51868944611012412, 10373788922202482, 20747577844404965, 41495155688809930, 82990311377619859, 16598062275523972, 33196124551047944, 66392249102095887, 13278449820419177, 26556899640838355, 53113799281676710, 10622759856335342, 21245519712670684, 42491039425341368, 84982078850682736, 16996415770136547, 33992831540273094, 67985663080546189, 13597132616109238, 27194265232218475, 54388530464436951, 10877706092887390, 21755412185774780, 43510824371549561, 87021648743099121, 17404329748619824, 34808659497239649, 69617318994479297, 13923463798895859, 27846927597791719, 55693855195583438, 11138771039116688, 22277542078233375, 44555084156466750, 89110168312933500, 17822033662586700, 35644067325173400, 71288134650346800, 14257626930069360, 28515253860138720, 57030507720277440, 11406101544055488, 22812203088110976, 45624406176221952, 91248812352443904, 18249762470488781, 36499524940977562, 72999049881955123, 14599809976391025, 29199619952782049, 58399239905564099, 11679847981112820, 23359695962225640, 46719391924451279, 93438783848902558, 18687756769780512, 37375513539561023, 74751027079122046, 14950205415824409, 29900410831648819, 59800821663297637, 11960164332659527, 23920328665319055, 47840657330638110, 95681314661276219, 19136262932255244, 38272525864510488, 76545051729020976, 15309010345804195, 30618020691608390, 61236041383216780, 12247208276643356, 24494416553286712, 48988833106573424, 97977666213146849, 19595533242629370, 39191066485258739, 78382132970517479, 15676426594103496, 31352853188206992, 62705706376413983, 12541141275282797, 25082282550565593, 50164565101131187, 10032913020226237, 20065826040452475, 40131652080904949, 80263304161809898, 16052660832361980, 32105321664723959, 64210643329447919, 12842128665889584, 25684257331779168, 51368514663558335, 10273702932711667, 20547405865423334, 41094811730846668, 82189623461693336, 16437924692338667, 32875849384677334, 65751698769354669, 13150339753870934, 26300679507741868, 52601359015483735, 10520271803096747, 21040543606193494, 42081087212386988, 84162174424773976, 16832434884923692028357, 12420144738405671, 24840289476811343, 49680578953622686, 99361157907245372, 19872231581449074, 39744463162898149, 79488926325796297, 15897785265159259, 31795570530318519, 63591141060637038, 12718228212127408, 25436456424254815, 50872912848509630, 10174582569701926, 20349165139403852, 40698330278807704, 81396660557615409, 16279332111523082, 32558664223046163, 65117328446092327, 13023465689218465, 26046931378436931, 52093862756873862, 10418772551374772, 20837545102749545, 41675090205499089, 83350180410998178, 16670036082199636, 33340072164399271, 66680144328798543, 13336028865759709, 26672057731519417, 53344115463038834, 10668823092607767, 21337646185215534, 42675292370431067, 85350584740862135, 17070116948172427, 34140233896344854, 68280467792689708, 13656093558537942, 27312187117075883, 54624374234151766, 10924874846830353, 21849749693660706, 43699499387321413, 87398998774642826, 17479799754928565, 34959599509857130, 69919199019714261, 13983839803942852, 27967679607885704, 55935359215771409, 11187071843154282, 22374143686308563, 44748287372617127, 89496574745234254, 17899314949046851, 35798629898093702, 71597259796187403, 14319451959237481, 28638903918474961, 57277807836949922, 11455561567389984, 22911123134779969, 45822246269559938, 91644492539119876, 18328898507823975, 36657797015647950, 73315594031295901, 14663118806259180, 29326237612518360, 58652475225036721, 11730495045007344, 23460990090014688, 46921980180029376, 93843960360058753, 18768792072011751, 37537584144023501, 75075168288047002, 15015033657609400, 30030067315218801, 60060134630437602, 12012026926087520, 24024053852175041, 48048107704350081, 96096215408700163, 19219243081740033, 38438486163480065, 76876972326960130, 15375394465392026, 30750788930784052, 61501577861568104, 12300315572313621, 24600631144627242, 49201262289254483, 98402524578508967, 19680504915701793, 39361009831403587, 78722019662807173, 15744403932561435, 31488807865122869, 62977615730245739, 12595523146049148, 25191046292098296, 50382092584196591, 10076418516839318, 20152837033678636, 40305674067357273, 80611348134714546, 16122269626942909, 32244539253885818, 64489078507771637, 12897815701554327, 25795631403108655, 51591262806217309, 10318252561243462, 20636505122486924, 41273010244973847, 82546020489947695, 16509204097989539, 33018408195979078, 66036816391958156, 13207363278391631, 26414726556783262, 52829453113566525, 10565890622713305, 21131781245426610, 42263562490853220, 84527124981706439, 16905424996341288, 33810849992682576, 67621699985365152, 13524339997073030, 27048679994146061, 54097359988292121, 10819471997658424, 21638943995316848, 43277887990633697, 86555775981267394, 17311155196253479, 34622310392506958, 69244620785013915, 13848924157002783, 27697848314005566, 55395696628011132, 11079139325602226, 22158278651204453, 44316557302408906, 88633114604817811, 17726622920963562, 35453245841927125, 70906491683854249, 14181298336770850, 28362596673541700, 56725193347083399, 11345038669416680, 22690077338833360, 45380154677666719, 90760309355333439, 18152061871066688, 36304123742133376, 72608247484266751, 14521649496853350, 29043298993706700, 58086597987413401, 11617319597482680, 23234639194965360, 46469278389930721, 92938556779861441, 18587711355972288, 37175422711944577, 74350845423889153, 14870169084777831, 29740338169555661, 59480676339111323, 11896135267822265, 23792270535644529, 47584541071289058, 95169082142578116, 19033816428515623, 38067632857031246, 76135265714062493, 15227053142812499, 30454106285624997, 60908212571249994, 12181642514249999, 24363285028499998, 48726570056999995, 97453140113999991, 19490628022799998, 38981256045599996, 77962512091199993, 15592502418239999, 31185004836479997, 62370009672959994, 12474001934591999, 24948003869183998, 49896007738367995, 99792015476735991, 19958403095347198, 39916806190694396, 79833612381388792, 15966722476277758, 31933444952555517, 63866889905111034, 12773377981022207, 25546755962044414, 51093511924088827, 10218702384817765, 20437404769635531, 40874809539271062, 81749619078542123, 16349923815708425, 32699847631416849, 65399695262833699, 13079939052566740, 26159878105133480, 52319756210266959, 10463951242053392, 20927902484106784, 41855804968213567, 83711609936427134, 16742321987285427, 33484643974570854, 66969287949141708, 13393857589828342, 26787715179656683, 53575430359313366, 10715086071862673, 21430172143725346, 42860344287450693, 85720688574901386, 17144137714980277, 34288275429960554, 68576550859921109, 13715310171984222, 27430620343968443, 54861240687936887, 10972248137587377, 21944496275174755, 43888992550349509, 87777985100699019, 17555597020139804, 35111194040279608, 70222388080559215, 14044477616111843, 28088955232223686, 56177910464447372, 11235582092889474, 22471164185778949, 44942328371557898, 89884656743115795};

const double _10en[324 * 2 + 1] = {1e-324, 1e-323, 1e-322, 1e-321, 1e-320, 1e-319, 1e-318, 1e-317, 1e-316, 1e-315, 1e-314, 1e-313, 1e-312, 1e-311, 1e-310, 1e-309, 1e-308, 1e-307, 1e-306, 1e-305, 1e-304, 1e-303, 1e-302, 1e-301, 1e-300, 1e-299, 1e-298, 1e-297, 1e-296, 1e-295, 1e-294, 1e-293, 1e-292, 1e-291, 1e-290, 1e-289, 1e-288, 1e-287, 1e-286, 1e-285, 1e-284, 1e-283, 1e-282, 1e-281, 1e-280, 1e-279, 1e-278, 1e-277, 1e-276, 1e-275, 1e-274, 1e-273, 1e-272, 1e-271, 1e-270, 1e-269, 1e-268, 1e-267, 1e-266, 1e-265, 1e-264, 1e-263, 1e-262, 1e-261, 1e-260, 1e-259, 1e-258, 1e-257, 1e-256, 1e-255, 1e-254, 1e-253, 1e-252, 1e-251, 1e-250, 1e-249, 1e-248, 1e-247, 1e-246, 1e-245, 1e-244, 1e-243, 1e-242, 1e-241, 1e-240, 1e-239, 1e-238, 1e-237, 1e-236, 1e-235, 1e-234, 1e-233, 1e-232, 1e-231, 1e-230, 1e-229, 1e-228, 1e-227, 1e-226, 1e-225, 1e-224, 1e-223, 1e-222, 1e-221, 1e-220, 1e-219, 1e-218, 1e-217, 1e-216, 1e-215, 1e-214, 1e-213, 1e-212, 1e-211, 1e-210, 1e-209, 1e-208, 1e-207, 1e-206, 1e-205, 1e-204, 1e-203, 1e-202, 1e-201, 1e-200, 1e-199, 1e-198, 1e-197, 1e-196, 1e-195, 1e-194, 1e-193, 1e-192, 1e-191, 1e-190, 1e-189, 1e-188, 1e-187, 1e-186, 1e-185, 1e-184, 1e-183, 1e-182, 1e-181, 1e-180, 1e-179, 1e-178, 1e-177, 1e-176, 1e-175, 1e-174, 1e-173, 1e-172, 1e-171, 1e-170, 1e-169, 1e-168, 1e-167, 1e-166, 1e-165, 1e-164, 1e-163, 1e-162, 1e-161, 1e-160, 1e-159, 1e-158, 1e-157, 1e-156, 1e-155, 1e-154, 1e-153, 1e-152, 1e-151, 1e-150, 1e-149, 1e-148, 1e-147, 1e-146, 1e-145, 1e-144, 1e-143, 1e-142, 1e-141, 1e-140, 1e-139, 1e-138, 1e-137, 1e-136, 1e-135, 1e-134, 1e-133, 1e-132, 1e-131, 1e-130, 1e-129, 1e-128, 1e-127, 1e-126, 1e-125, 1e-124, 1e-123, 1e-122, 1e-121, 1e-120, 1e-119, 1e-118, 1e-117, 1e-116, 1e-115, 1e-114, 1e-113, 1e-112, 1e-111, 1e-110, 1e-109, 1e-108, 1e-107, 1e-106, 1e-105, 1e-104, 1e-103, 1e-102, 1e-101, 1e-100, 1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, 1e-90, 1e-89, 1e-88, 1e-87, 1e-86, 1e-85, 1e-84, 1e-83, 1e-82, 1e-81, 1e-80, 1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73, 1e-72, 1e-71, 1e-70, 1e-69, 1e-68, 1e-67, 1e-66, 1e-65, 1e-64, 1e-63, 1e-62, 1e-61, 1e-60, 1e-59, 1e-58, 1e-57, 1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40, 1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, 1e-19, 1e-18, 1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39, 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49, 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59, 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69, 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79, 1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89, 1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99, 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109, 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139, 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169, 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179, 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189, 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199, 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209, 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219, 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229, 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239, 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249, 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259, 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269, 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279, 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289, 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299, 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16};

const uint64_t one_e_16 = 10000000000000000ull;
void mult64to128(uint64_t op1, uint64_t op2, uint64_t *hi, uint64_t *lo)
{
	uint64_t u1 = (op1 & 0xffffffff);
	uint64_t v1 = (op2 & 0xffffffff);
	uint64_t t = (u1 * v1);
	uint64_t w3 = (t & 0xffffffff);
	uint64_t k = (t >> 32);

	op1 >>= 32;
	t = (op1 * v1) + k;
	k = (t & 0xffffffff);
	uint64_t w1 = (t >> 32);

	op2 >>= 32;
	t = (u1 * op2) + k;
	k = (t >> 32);

	*hi = (op1 * op2) + w1 + k;
	*lo = (t << 32) + w3;
}

void print_double(double value)
{
	unsigned long long int_value;
	memcpy(&int_value, &value, sizeof(value));
	std::cout << "binary double : "
			  << std::bitset<1>(int_value >> 63) << ' '
			  << std::bitset<11>((int_value >> 52) & 0x7FF) << ' '
			  << std::bitset<52>(int_value & 0xFFFFFFFFFFFFF) << ' '
			  << "ieee754 exp=" << ((int(int_value >> 52) & 0x7FF) - 1023) << '\n';
}
double fast_exp(double y)
{
	double d;
	*(reinterpret_cast<int *>(&d) + 0) = 0;
	*(reinterpret_cast<int *>(&d) + 1) = static_cast<int>(1048576.0 * (y / (0.69314718055994530942) + 1022.9420151853));
	return d;
}
// const double MAGIC_NUMBER{ 1 * (1ll << 52)  }; // 1.5* 2**52
// const double MAGIC_NUMBER2{1.5 * (1ll << 52)}; // 1.5* 2**52
const double MAGIC_NUMBER{0x0018000000000000}; // 6755399441055744
// const double MAGIC_NUMBER {0x0010000000000000};//1.5 * 2**52
int64_t double_to_int64(double num)
{
	// return num;
	return (int64_t)((num + MAGIC_NUMBER) - MAGIC_NUMBER);
}
int getexponent(double num)
{
	return ((((*(uint64_t *)(&num)) >> 52) & 0x7FF) - 1023);
}
uint64_t getfrac(double num)
{
	return ((*(uint64_t *)&num) & 0xFFFFFFFFFFFFF) | (1ll << 52);
}
uint64_t getfracnot1(double num)
{
	return ((*(uint64_t *)&num) & 0xFFFFFFFFFFFFF);
}
// 生成一个[min, max)范围内的随机double数
double generateRandomDouble(double min, double max)
{
	// 使用当前时间作为随机数生成器的种子，以获得每次运行程序时不同的随机序列
	static std::mt19937 generator((std::time(0)));				   // Mersenne Twister引擎
	std::uniform_real_distribution<double> distribution(min, max); // 定义均匀分布的范围
	return distribution(generator);
}

std::string doubleToScientific(double value, int n)
{
	std::stringstream ss;
	// 设置输出格式为科学记数法，并保留一定精度，例如6位小数
	ss << std::scientific << std::setprecision(n) << value;
	return ss.str();
}
auto fastPowDouble = [](double a, int n) -> double
{
	// 绝大多数都比较小，在16以内
	switch (n) // 编译器会优化为跳表
	{
	case 0:
		return 1.0;
	case 1:
		return a;
	case 2:
		return a * a;
	case 3:
		return a * a * a;
	case 4:
		return a * a * a * a;
	case 5:
		return a * a * a * a * a;
	case 6:
		return a * a * a * a * a * a;
	case 7:
		return a * a * a * a * a * a * a;
	case 8:
		return a * a * a * a * a * a * a * a;
	case 9:
		return a * a * a * a * a * a * a * a * a;
	case 10:
		return a * a * a * a * a * a * a * a * a * a;
	case 11:
		return a * a * a * a * a * a * a * a * a * a * a;
	case 12:
		return a * a * a * a * a * a * a * a * a * a * a * a;
	case 13:
		return a * a * a * a * a * a * a * a * a * a * a * a * a;
	case 14:
		return a * a * a * a * a * a * a * a * a * a * a * a * a * a;
	case 15:
		return a * a * a * a * a * a * a * a * a * a * a * a * a * a * a;
	case 16:
		return a * a * a * a * a * a * a * a * a * a * a * a * a * a * a * a;
	}
	double result = 1.0;
	while (n > 0)
	{
		if (n & 1)
			result *= a; // 如果n是奇数，则将当前的a累乘到结果中
		n >>= 1;		 // n右移一位（相当于除以2）
		a *= a;			 // a自乘
	}
	return result;
};
int getb(double value)
{
	const double r = log10(2.0); // 0.30102999566398120;
	// int exponent = static_cast<int>(((*(reinterpret_cast<uint64_t *>(&value)) >> 52) & 0x7FF) - 1023) * r; // 5 operation
	int exponent = int((((*(uint64_t *)(&value)) >> 52) & 0x7FF) - 1023) * r;
	int condition = (std::fabs(value) >= 1.0);
	int b = exponent + condition - (std::fabs(value) < _10en[exponent + condition + 324]);
	return value == 0 ? 0 : b;
}
double getpow10(int n)
{
	return _10en[n + 324];
}
double getpow10n_mul_pow2n(int n, int m, int i = 0)
{
	// 10的n次方除以2的m次方
	// return
	double res = getpow10(n) * pow(2, m);
	int pow5 = n;
	int pow2 = n + m;
	res = pow(5.0, n) * pow(2.0, n + m);
	// printf("i=%d pow5=%d pow2=%d ", i, pow5, pow2);
	return res;
}
class info
{
public:
	int index;
	double scale1, scale2;
	int is_change; // 1时scale1和scale2有效
				   // 0时scale1有效
	struct
	{
		int pow5;
		int pow2;
	} s5[2];
	struct
	{
		int pow10;
		int pow2;
	} s10[2];
	void print_info()
	{
		printf("index=%d ", index);
		if (is_change)
		{
			printf("s5[0].pow5=%d s5[0].pow2=%d  s10[0].pow10=%d s10[0].pow2=%d ", s5[0].pow5, s5[0].pow2, s10[0].pow10, s10[0].pow2);
			printf("s5[1].pow5=%d s5[1].pow2=%d  s10[1].pow10=%d s10[1].pow2=%d ", s5[1].pow5, s5[1].pow2, s10[1].pow10, s10[1].pow2);
			printf("scale1=%.16le scale2=%.16le\n", scale1, scale2);
		}
		else
		{
			printf("s5[0].pow5=%d s5[0].pow2=%d  s10[0].pow10=%d s10[0].pow2=%d ", s5[0].pow5, s5[0].pow2, s10[0].pow10, s10[0].pow2);
			printf("scale=%.16le\n", scale1);
		}
	}
};
std::vector<info> all_info(2046);
void info_init()
{
	const double r = 1.0 / log2(10.0);
	int pow10 = 16; // 1-2时scale=1e16*2**-52;
	int pow2 = -52;
	for (long long int i = 1 + 1022 - 1023; i <= 2046 - 1023; ++i)
	{
		if (int(i * r) != int((i + 1) * r))
		{
			int all_info_index = i + 1022;
			if (all_info_index < 0 || all_info_index >= 2046)
			{
				printf("error i=%d\n", i);
				exit(1);
			}
			all_info[all_info_index].index = i;
			all_info[all_info_index].is_change = 1;

			double scale1 = getpow10n_mul_pow2n(pow10, pow2, i);
			{
				all_info[all_info_index].scale1 = scale1;
				all_info[all_info_index].s10[0].pow10 = pow10;
				all_info[all_info_index].s10[0].pow2 = pow2;
				all_info[all_info_index].s5[0].pow5 = pow10;
				all_info[all_info_index].s5[0].pow2 = pow2 + pow10;
			}

			pow10--;
			double scale2 = getpow10n_mul_pow2n(pow10, pow2, i);
			{
				all_info[all_info_index].scale2 = scale2;
				all_info[all_info_index].s10[1].pow10 = pow10;
				all_info[all_info_index].s10[1].pow2 = pow2;
				all_info[all_info_index].s5[1].pow5 = pow10;
				all_info[all_info_index].s5[1].pow2 = pow2 + pow10;
			}
			// printf("i=%d scale1=%.16le scale2=%.16le\n", i, scale1, scale2);
		}
		else
		{
			double scale = getpow10n_mul_pow2n(pow10, pow2, i);
			// printf("i=%d pow10=%d,pow2=%d,scale=%.16le\n", i, pow10, pow2, scale);
			int all_info_index = i + 1022;
			if (all_info_index < 0 || all_info_index >= 2046)
			{
				printf("error i=%d\n", i);
				exit(1);
			}
			all_info[all_info_index].index = i;
			all_info[all_info_index].is_change = 0;
			all_info[all_info_index].scale1 = scale;
			all_info[all_info_index].s10[0].pow10 = pow10;
			all_info[all_info_index].s10[0].pow2 = pow2;
			all_info[all_info_index].s5[0].pow5 = pow10;
			all_info[all_info_index].s5[0].pow2 = pow2 + pow10;
		}
		pow2++;
	}
	pow10 = 17;
	pow2 = -53;
	for (long long int i = -1 + 1023 - 1023; i >= 1 - 1023; --i)
	{
		if (int(i * r) != int((i + 1) * r))
		{
			int all_info_index = i + 1022;
			if (all_info_index < 0 || all_info_index >= 2046)
			{
				printf("error i=%d\n", i);
				exit(1);
			}
			all_info[all_info_index].index = i;
			all_info[all_info_index].is_change = 1;

			double scale2 = getpow10n_mul_pow2n(pow10, pow2, i);

			{
				all_info[all_info_index].scale2 = scale2;
				all_info[all_info_index].s10[1].pow10 = pow10;
				all_info[all_info_index].s10[1].pow2 = pow2;
				all_info[all_info_index].s5[1].pow5 = pow10;
				all_info[all_info_index].s5[1].pow2 = pow2 + pow10;
			}

			pow10++;
			double scale1 = getpow10n_mul_pow2n(pow10, pow2, i);

			{
				all_info[all_info_index].scale1 = scale1;
				all_info[all_info_index].s10[0].pow10 = pow10;
				all_info[all_info_index].s10[0].pow2 = pow2;
				all_info[all_info_index].s5[0].pow5 = pow10;
				all_info[all_info_index].s5[0].pow2 = pow2 + pow10;
			}

			// printf("i=%d scale1=%.16le scale2=%.16le\n",i, scale1,scale2);
		}
		else
		{
			double scale = getpow10n_mul_pow2n(pow10, pow2, i);

			int all_info_index = i + 1022;
			if (all_info_index < 0 || all_info_index >= 2046)
			{
				printf("error i=%d\n", i);
				exit(1);
			}
			all_info[all_info_index].index = i;
			all_info[all_info_index].is_change = 0;
			all_info[all_info_index].scale1 = scale;
			all_info[all_info_index].s10[0].pow10 = pow10;
			all_info[all_info_index].s10[0].pow2 = pow2;
			all_info[all_info_index].s5[0].pow5 = pow10;
			all_info[all_info_index].s5[0].pow2 = pow2 + pow10;
			// printf("i=%d pow10=%d,pow2=%d,scale=%.16le\n",i,pow10,pow2,scale);
		}
		pow2--;
	}
}
template <int t = 0, int Precision = 16, int All_double = 32>
int my_dou_to_sci_avx512(double *value, char **buffer, char *buffer_s = 0)
{
	// int every
	const int is_avx512 = 0;
	const double r = 1.0 / log2(10.0); // 0.30102999566398120
	const double r2 = log2(10.0);
	// 为了提高速度，采用 avx512 一次性处理8*n个double数
	static const short short_array[100] = {12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640,
										   12337, 12593, 12849, 13105, 13361, 13617, 13873, 14129, 14385, 14641,
										   12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642,
										   12339, 12595, 12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643,
										   12340, 12596, 12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644,
										   12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645,
										   12342, 12598, 12854, 13110, 13366, 13622, 13878, 14134, 14390, 14646,
										   12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391, 14647,
										   12344, 12600, 12856, 13112, 13368, 13624, 13880, 14136, 14392, 14648,
										   12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649};

	static const int write_array[100] = {808452096, 825229312, 842006528, 858783744, 875560960, 892338176, 909115392, 925892608, 942669824, 959447040,
										 808517632, 825294848, 842072064, 858849280, 875626496, 892403712, 909180928, 925958144, 942735360, 959512576,
										 808583168, 825360384, 842137600, 858914816, 875692032, 892469248, 909246464, 926023680, 942800896, 959578112,
										 808648704, 825425920, 842203136, 858980352, 875757568, 892534784, 909312000, 926089216, 942866432, 959643648,
										 808714240, 825491456, 842268672, 859045888, 875823104, 892600320, 909377536, 926154752, 942931968, 959709184,
										 808779776, 825556992, 842334208, 859111424, 875888640, 892665856, 909443072, 926220288, 942997504, 959774720,
										 808845312, 825622528, 842399744, 859176960, 875954176, 892731392, 909508608, 926285824, 943063040, 959840256,
										 808910848, 825688064, 842465280, 859242496, 876019712, 892796928, 909574144, 926351360, 943128576, 959905792,
										 808976384, 825753600, 842530816, 859308032, 876085248, 892862464, 909639680, 926416896, 943194112, 959971328,
										 809041920, 825819136, 842596352, 859373568, 876150784, 892928000, 909705216, 926482432, 943259648, 960036864};
	for (int i = 0; i < 100; i++)
	{
		// write_array[i]=( (i%2) ? short('-' * 256 + 'e') : short('+' * 256 + 'e')  ) + short_array[i]*(1<<16);
		// write_array[i] = short_array[i] * (1 << 16);
		// if(t==1)printf("%d,",write_array[i]);
	}
	constexpr int group = 8;						// avx512 = 8 double
	constexpr int group_count = All_double / group; // 16:2 24:3 32:4
	__m512d value_8[group_count];
	__m512i value_8i[group_count];
	//__m512d value_8_origin[group_count];
	for (int i = 0; i < group_count; ++i)
	{
		// value_8[i] = _mm512_abs_pd(_mm512_loadu_pd(&value[i * group])); // 加载数据
		// value_8i[i] = _mm512_abs_epi64(_mm512_loadu_epi64(&value[i * group])); // 以int64方式存储
		value_8i[i] = _mm512_loadu_epi64(&value[i * group]);	  // 以int64方式存储
		value_8[i] = (__m512d(value_8i[i] & ((1ull << 63) - 1))); // 绝对值
																  // value_8_origin[i] = __m512d(value_8i[i]);                 //原始值
	}
	__m512i exponent_8[group_count];
	// int index[All_double] = {0};
	int64_t exponent[All_double];
	// int every_length[All_double];
	__m512i every_length_8[group_count];
	int every_start_pos[All_double + 1] = {0};
	//__m512d final_result[group_count];
#if 1
	if (0)
		for (int i = 0; i < group_count; ++i)
		{

			for (int j = 0; j < group; ++j)
			{
				// buffer[i * group + j][0] = '-';

				// index[i * group + j] = (value[i * group + j] < 0);

				if (value[i * group + j] < 0)
				{
					//(buffer[i * group + j][0]) = '-';
					// index[i * group + j] = 1;
					// value[i*group+j] = -value[i*group+j];
				}

				// exponent[i * group + j] = getb(value[i * group + j]);

				// const double r = 1.0 / log2(10.0); // 0.30102999566398120
				//  int exponent_tmp = int((((*(uint64_t *)(&value[i * group + j])) >> 52) & 0x7FF) - 1023) * (r);
				//  double num = std::fabs(value[i * group + j]) * _10en[-exponent_tmp + 308]; // one read , one operation
				//  value[i * group + j] = std::fabs(value[i * group + j]);
				//  exponent[i * group + j] = (exponent_tmp) + (num >= 10.0) - (num < 1.0);
			}

			// // 采用avx512指令
			__m512i exponent_8_tmp = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(((__m512i(value_8[i]) >> 52)) - 1023) * r);
			__m512i condition_8 = (0 + value_8[i] < 1.0);
			//__m512i exponent_8_tmp = _mm512_cvtpd_epi64(_mm512_cvtepi64_pd(((value_8i[i] >> 52) ) - 1023)*r);
			//__m512i _10en_index = (308 - exponent_8_tmp);
			//__m512i temp_8i = exponent_8_tmp + condition_8;
			//__m512i _10en_index = (308 + 1 + exponent_8_tmp + condition_8);
			__m512i _10en_index = (exponent_8_tmp + condition_8);
			// __m512d num_8 = value_8[i] * _mm512_set_pd(_10en[_10en_index[0]], _10en[_10en_index[1]],
			// 										   _10en[_10en_index[2]], _10en[_10en_index[3]],
			// 										   _10en[_10en_index[4]], _10en[_10en_index[5]],
			// 										   _10en[_10en_index[6]], _10en[_10en_index[7]]); // 有可能是倒序，后续注意一下
			//__m512d num_8 = value_8[i] * _mm512_i64gather_pd(_10en_index, _10en, 8);
			__m512d num_8_cmp = _mm512_i64gather_pd(_10en_index, &_10en[309 + 16], 8);

			// 提高速度，精度减少
			// __m512d num_8_mul10 = num_8 * 10.0;
			// __m512d num_8_div10 = num_8 * 0.1;
			// // auto mul10_mask = (num_8 >= 10.0);
			// auto div10_mask = _mm512_cmp_pd_mask(num_8, _mm512_set1_pd(10.0), _CMP_GE_OQ); //>=
			// auto mul10_mask = _mm512_cmp_pd_mask(num_8, _mm512_set1_pd(1.0), _CMP_LT_OQ);  //<
			// __m512d result = _mm512_mask_blend_pd(div10_mask, num_8, num_8_div10);
			// final_result[i] = _mm512_mask_blend_pd(mul10_mask, result, num_8_mul10);

			// auto num_8_cmp10 = (num_8 >= 10.0);
			// auto num_8_cmp0_1 = (num_8 < 1.0);
			// exponent_8[i] = (exponent_8_tmp - (num_8 >= 10.0) + (num_8 < 1.0)); // (num_8 >= 10.0) 条件成立时值为-1
			// auto cmp_result = (value_8[i] >= num_8_cmp);

			exponent_8[i] = (_10en_index - (0 + (value_8[i] >= num_8_cmp))); // (value_8[i] < num_8_cmp) 条件成立时值为-1

			exponent_8[i] = (value_8[i] == 0.0) ? 0 : exponent_8[i]; // value==0时 exponent=0;

			if (t == 1)
			{
				for (int j = 0; j < group; ++j)
				{
					// printf("num_8_cmp10[%d]=%lld ", j, num_8_cmp10[j]);
					// printf("num_8_cmp0_1[%d]=%lld ", j, num_8_cmp0_1[j]);
					// printf("num_d[%d]=%.16le ", j, num_8[j]);
					// printf("exponent_8_tmp[%d]=%lld  ", j, exponent_8_tmp[j]);
					// printf("exponent_8[%d][%d]=%lld cmp_result[%d]=%d\n", i, j, exponent_8[i][j],j,cmp_result[j]);
				}
			}

			_mm512_storeu_epi64(&exponent[i * group], exponent_8[i]);

			for (int j = 0; j < group; ++j)
			{
				// every_length[i * group + j] = index[i * group + j]				   /*value<0时有负号*/
				// 							  + (abs(exponent_8[i][j]) >= 100) + 2 /*exp>=100时为3,exp<100时为2*/
				// 							  + (Precision > 0)					   /*小数点*/
				// 							  + 1								   /*间隔空格个数*/
				// 							  + 1								   /*小数点前一位*/
				// 							  + Precision						   /*小数点后有几位*/
				// 							  + 2;								   /* 'e+' or 'e-' */
				// every_start_pos[i * group + j + 1] = every_start_pos[i * group + j] + every_length[i * group + j];

				if (t == 1)
				{
					// printf("every_length[%d]=%d\n", i * group + j, int(every_length[i * group + j]));
				}
			}

			// every_length_8[i]
			//__m512i every_length_8_tmp
			every_length_8[i] = (1 + (__m512d(value_8i[i]) >= 0)) +				  /*value<0时有负号*/
								(1 + (_mm512_abs_epi64(exponent_8[i]) < 100)) + 2 /*exp>=100时为3,exp<100时为2*/
								+ (Precision > 0)								  /*小数点*/
								+ 1												  /*间隔空格个数*/
								+ 1												  /*小数点前一位*/
								+ Precision										  /*小数点后有几位*/
								+ 2;											  /* 'e+' or 'e-' */
			for (int j = 0; j < group; ++j)
			{
				// every_start_pos[i * group + j + 1] = every_start_pos[i * group + j] + every_length_8_tmp[j];
			}

			if (t == 1)
			{ // 调试
			  // int64_t index_8[8];
			  // double index_8_d[8];
			  // _mm512_storeu_epi64(index_8, _10en_index);
			  // _mm512_storeu_pd(index_8_d, _mm512_cvtepi64_pd(((value_8i[i] >> 52) & 0x7FF) - 1023));
			  // auto index0 = index_8[0];
			  // auto index1 = index_8[1];
			  // auto index0_d = index_8_d[0];
			  // auto index1_d = index_8_d[1];
			  // auto exponent_8_0 = exponent_8[0][0];
			  // printf("_10en_index[0]=%lld _10en_index[1]=%lld\n", index0, index1);
			  // printf("_10en_index_d[0]=%lf _10en_index_d[1]=%lf\n", index0_d, index1_d);
			  // printf("exponent_8_0=%lld\n", exponent_8_0);
			}
		}
	else
	{
		for (int i = 0; i < group_count; ++i)
		{
			// // 采用avx512指令
			//__m512i exponent_8_tmp = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(((value_8i[i] >> 52) & 0x7FF) - 1023) * r);
			//__m512i condition_8 = (value_8[i] < 1.0);
			__m512i _10en_index = (_mm512_cvttpd_epi64(_mm512_cvtepi64_pd(((__m512i(value_8[i]) >> 52)) - 1023) * r) + (value_8[i] < 1.0));
			//__m512d num_8_cmp = _mm512_i64gather_pd(_10en_index, &_10en[309], 8);
			// exponent_8[i] = (_10en_index - ((value_8[i] >= num_8_cmp))); // (value_8[i] < num_8_cmp) 条件成立时值为-1
			exponent_8[i] = (value_8[i] == 0.0) ? 0 : (_10en_index - ((value_8[i] >= _mm512_i64gather_pd(_10en_index, &_10en[309 + 16], 8)))); // value==0时 exponent=0;
			_mm512_storeu_epi64(&exponent[i * group], exponent_8[i]);
			// every_length_8[i] = (1 + (__m512d(value_8i[i]) >= 0)) +				  /*value<0时有负号*/
			// 					(1 + (_mm512_abs_epi64(exponent_8[i]) < 100)) + 2 /*exp>=100时为3,exp<100时为2*/
			// 					+ (Precision > 0)								  /*小数点*/
			// 					+ 1												  /*间隔空格个数*/
			// 					+ 1												  /*小数点前一位*/
			// 					+ Precision										  /*小数点后有几位*/
			// 					+ 2;											  /* 'e+' or 'e-' */
			every_length_8[i] = (1 + (__m512d(value_8i[i]) >= 0)) +						 /*value<0时有负号*/
								(1 + ((value_8[i] < 1e100) & (value_8[i] >= 1e-99))) + 2 /*exp>=100时为3,exp<100时为2*/
								+ (Precision > 0)										 /*小数点*/
								+ 1														 /*间隔空格个数*/
								+ 1														 /*小数点前一位*/
								+ Precision												 /*小数点后有几位*/
								+ 2;													 /* 'e+' or 'e-' */
		}
	}
	// 提高速度，
	// int prefix_sum = 0;

	for (int i = 0; i < group_count; ++i)
	{
		for (int j = 0; j < group; ++j)
		{
			// prefix_sum +=  every_length_8[i][j] ;
			// every_start_pos[i * group + j + 1] = prefix_sum;
			every_start_pos[i * group + j + 1] = every_start_pos[i * group + j] + every_length_8[i][j]; // 计算前缀和
																										// if(t==1)printf("every_start_pos[%d]=%d\n",i*group+j, every_start_pos[i * group + j]);
		}
	}
#else
	__m512i exponent_8_tmp[group_count];
	__m512i _10en_index[group_count];
	__m512d num_8[group_count];
	const double r = 1.0 / log2(10.0); // 0.30102999566398120
	for (int i = 0; i < group_count; ++i)
	{

		for (int j = 0; j < group; ++j)
		{
			if (value[i * group + j] < 0)
			{
				(buffer[i * group + j][index[i * group + j]++]) = '-';
			}
		}
	}
	for (int i = 0; i < group_count; ++i)
	{
		exponent_8_tmp[i] = _mm512_cvtpd_epi64(_mm512_cvtepi64_pd(((value_8i[i] >> 52) & 0x7FF) - 1023) * r);
	}
	for (int i = 0; i < group_count; ++i)
	{
		_10en_index[i] = (308 - exponent_8_tmp[i]);
	}
	for (int i = 0; i < group_count; ++i)
	{
		num_8[i] = value_8[i] * _mm512_i64gather_pd(_10en_index[i], _10en, 8);
	}
	for (int i = 0; i < group_count; ++i)
	{
		exponent_8[i] = (exponent_8_tmp[i] + (num_8[i] >= 10.0) + (num_8[i] < 1.0));
	}
	for (int i = 0; i < group_count; ++i)
	{
		_mm512_storeu_epi64(&exponent[i * group], exponent_8[i]);
	}

	// 采用avx512指令
	// __m512i exponent_8_tmp = _mm512_cvtpd_epi64(_mm512_cvtepi64_pd(((value_8i[i] >> 52) & 0x7FF) - 1023) * r);
	// //__m512i exponent_8_tmp = _mm512_cvtpd_epi64(_mm512_cvtepi64_pd(((value_8i[i] >> 52) ) - 1023)*r);
	// __m512i _10en_index = (308 - exponent_8_tmp);
	// __m512d num_8 = value_8[i] * _mm512_i64gather_pd(_10en_index, _10en, 8);
	// exponent_8[i] = (exponent_8_tmp + (num_8 >= 10.0) + (num_8 < 1.0));
	// _mm512_storeu_epi64(&exponent[i * group], exponent_8[i]);

	if (t == 1)
	{ // 调试
	  // int64_t index_8[8];
	  // double index_8_d[8];
	  // _mm512_storeu_epi64(index_8, _10en_index);
	  // _mm512_storeu_pd(index_8_d, _mm512_cvtepi64_pd(((value_8i[i] >> 52) & 0x7FF) - 1023));
	  // auto index0 = index_8[0];
	  // auto index1 = index_8[1];
	  // auto index0_d = index_8_d[0];
	  // auto index1_d = index_8_d[1];
	  // auto exponent_8_0 = exponent_8[0][0];
	  // printf("_10en_index[0]=%lld _10en_index[1]=%lld\n", index0, index1);
	  // printf("_10en_index_d[0]=%lf _10en_index_d[1]=%lf\n", index0_d, index1_d);
	  // printf("exponent_8_0=%lld\n", exponent_8_0);
	}

#endif

	double tmp_num[All_double];
	int64_t num0123456[All_double];
	__m512i num0_rest_8[group_count];
	int64_t num123456[All_double];
	int64_t num0[All_double];
	__m512i num0_8[group_count];
	__m512i num_rest_8[group_count];
	for (int i = 0; i < group_count; ++i)
	{
		if (0)
		{
			for (int j = 0; j < group; ++j)
			{
				// if (exponent[i * group + j] <= (-308 + (Precision - 1))) [[unlikely]] // 1% 概率,随机数的情况下 branch 2
				// {																	  //-303      branch 2
				// 	tmp_num[i * group + j] = value[i * group + j] * _10en[-(exponent[i * group + j] - (-308 + Precision)) + 308] * 1e308;
				// }
				// else
				// {
				// 	tmp_num[i * group + j] = value[i * group + j] * _10en[(-exponent[i * group + j]) + Precision + 308];
				// }

				// tmp_num[i * group + j] = value[i * group + j] * _10en[(-exponent[i * group + j]) + Precision + 308];
				// tmp_num[i * group + j] = final_result[i] * _mm512_set1_pd(_10en[Precision + 308]);

				// num0123456[i * group + j] = double_to_int64(tmp_num[i * group + j]);

				// avx512
				// __m512d tmp_num_8 = final_result[i] * _mm512_set1_pd(_10en[Precision + 308]);
				// if (Precision <= 14)
				// {
				// 	num0_rest_8[i] = _mm512_cvtpd_epi64(tmp_num_8 + MAGIC_NUMBER - MAGIC_NUMBER);
				// }
				// else if (Precision == 15)
				// {
				// 	const double magic_number = 1ll << 52;
				// 	num0_rest_8[i] = _mm512_cvtpd_epi64(tmp_num_8 + magic_number - magic_number);
				// }
				// else if (Precision == 16)
				// {
				// 	num0_rest_8[i] = _mm512_cvtpd_epi64(tmp_num_8);
				// }
				// num0_rest_8[i] = _mm512_cvtpd_epi64(tmp_num_8);
				// num0_rest_8[i] = _mm512_cvtpd_epi64(tmp_num_8 +MAGIC_NUMBER-MAGIC_NUMBER);
				//_mm512_storeu_epi64(&num0123456[i * group],num0_rest_8);
			}
		}
		else
		{
			if (0)
			{
				// _mm512_storeu_epi64(&num0123456[i * group],
				// 				   _mm512_cvtpd_epi64(value_8[i] * _mm512_set_pd(_10en[-exponent[i * group + 0] + Precision + 308], _10en[-exponent[i * group + 1] + Precision + 308],
				// 																 _10en[-exponent[i * group + 2] + Precision + 308], _10en[-exponent[i * group + 3] + Precision + 308],
				// 																 _10en[-exponent[i * group + 4] + Precision + 308], _10en[-exponent[i * group + 5] + Precision + 308],
				// 																 _10en[-exponent[i * group + 6] + Precision + 308], _10en[-exponent[i * group + 7] + Precision + 308])
				// 																 + MAGIC_NUMBER - MAGIC_NUMBER));
				num0_rest_8[i] = _mm512_cvtpd_epi64(value_8[i] * _mm512_set_pd(_10en[-exponent[i * group + 0] + Precision + 308], _10en[-exponent[i * group + 1] + Precision + 308],
																			   _10en[-exponent[i * group + 2] + Precision + 308], _10en[-exponent[i * group + 3] + Precision + 308],
																			   _10en[-exponent[i * group + 4] + Precision + 308], _10en[-exponent[i * group + 5] + Precision + 308],
																			   _10en[-exponent[i * group + 6] + Precision + 308], _10en[-exponent[i * group + 7] + Precision + 308]));
			}
			else
			{
				__m512i exponent_8_tmp = (Precision + 324 - exponent_8[i]);
				// num0_rest_8[i] = _mm512_cvtpd_epi64(value_8[i] * _mm512_i64gather_pd(exponent_8_tmp, _10en, 8));
				__m512d tmp_num_8 = value_8[i] * _mm512_i64gather_pd(exponent_8_tmp, _10en, 8);
				tmp_num_8 *= exponent_8_tmp > 616 ? 1e308 : 1;

				if (Precision <= 14)
				{
					num0_rest_8[i] = _mm512_cvtpd_epi64(tmp_num_8 + MAGIC_NUMBER - MAGIC_NUMBER); // 1.5*(1<<52)
				}
				else if (Precision == 15)
				{
					const double magic_number = 1ll << 52;
					num0_rest_8[i] = _mm512_cvtpd_epi64(tmp_num_8 + magic_number - magic_number);
				}
				else if (Precision == 16)
				{
					// num0_rest_8[i] = _mm512_cvtpd_epi64(tmp_num_8);

					// compute value的f和e,获取10的-exp次方，相乘
					__m512i value_8i_f = (value_8i[i] & ((1ll << 52) - 1)) + (1ll << 52);
					__m512i value_8i_e = ((value_8i[i] >> 52) & 0x7ff) - 1023 - 52;
					__m512i pow10_8_f = _mm512_i64gather_epi64(-exponent_8[i] + 343 + Precision, powers_ten, sizeof(uint64_t));
					//__m512i pow10_8_e = _mm512_i64gather_epi64(-exponent_8[i] + 343 + Precision, powers_ten_e, sizeof(int64_t));
					__m512i pow10_8_e = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(-exponent_8[i] + Precision) * r2) - 63 - (1 + (-exponent_8[i] + Precision) <= 0);
					// int((-exponent)*r2)-63-(exponent>0)
					if (t == 1)
					{
						for (int j = 0; j < 8; ++j)
						{
							// printf("num0_rest_8[%d][%d]=%lld\n",i,j,num0_rest_8[i][j]);
							// printf("pow10_8_f[%d][%d]=%llx ",i,j,pow10_8_f[j]);
							// printf("pow10_8_f[%d][%d]=%d\n",i,j,pow10_8_e[j]);
						}
					}
					value_8i_f <<= 11;
					value_8i_e -= 11;
					const uint64_t M32 = 0xFFFFFFFF;
					__m512i a = _mm512_srli_epi64(value_8i_f, 32);
					__m512i b = value_8i_f & M32;
					__m512i c = _mm512_srli_epi64(pow10_8_f, 32);
					__m512i d = pow10_8_f & M32;
					__m512i ac = _mm512_mul_epu32(a, c);
					__m512i bd = _mm512_mul_epu32(b, b);
					__m512i ad = _mm512_mul_epu32(a, d);
					__m512i bc = _mm512_mul_epu32(b, c);
					__m512i hi = ac + _mm512_srli_epi64(ad, 32) + _mm512_srli_epi64(bc, 32);
					__m512i lo = bd + (ad & M32) + (bc & M32);
					__m512i res_f = hi + _mm512_srli_epi64(lo, 63);
					__m512i res_e = value_8i_e + pow10_8_e + 64;
					__m512i add_num = _mm512_srlv_epi64(res_f, (-res_e - 1)) & 1;
					num0_rest_8[i] = _mm512_srlv_epi64(res_f, (-res_e)) + add_num;

					if (t == 1)
					{
						for (int j = 0; j < 8; ++j)
						{
							// printf("value_8i_f[%d][%d]=%llx ",i,j,value_8i_f[j]);
							// printf("a[%d][%d]=%llx ",i,j,a[j]);
							// printf("b[%d][%d]=%llx ",i,j,b[j]);
							// printf("res_f[%d][%d]=%llx ",i,j,res_f[j]);
							// printf("res_e[%d][%d]=%d ",i,j,res_e[j]);
							// printf("add_num[%d][%d]=%d ",i,j,add_num[j]);
							// printf("num0_rest_8[%d][%d]=%llu\n",i,j,num0_rest_8[i][j]);
						}
					}

					// uint64_t hi = ac + (ad >> 32) + (bc >> 32);
					// uint64_t lo = bd + (ad & M32) + (bc & M32);
					// return DiyFp(hi + (lo >> 63), e + rhs.e + 64);
					// uint64_t add_num = ((mul_result.f >> (-mul_result.e - 1)) & 1);
					// num0123456 = (mul_result.f >> (-mul_result.e)) + add_num;

					if (t == 1)
					{
						for (int j = 0; j < group; ++j)
						{
							// printf("value_8[%d][%d]=%.16le   num0_rest_8[%d][%d] = %lld\n",i,j,value_8[i][j],i,j,num0_rest_8[i][j]);
						}
					}
				}

				num0_8[i] = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(num0_rest_8[i]) * _10en[-Precision + 324]);

				num0_8[i] -= ((num0_rest_8[i] - num0_8[i] * int64_t(_10en[Precision + 324])) >= 0) + 1;

				num_rest_8[i] = (num0_rest_8[i] - num0_8[i] * int64_t(_10en[Precision + 324]));

				//__m512i condition = ((num0_rest_8[i] - num0_8[i] * int64_t(_10en[Precision + 308]) ) >= 0) + 1 ;
				// num_rest_8[i] = condition ? (num0_rest_8[i] - num0_8[i] * int64_t(_10en[Precision + 308])) + int64_t(_10en[Precision + 308]) :
				// 							(num0_rest_8[i] - num0_8[i] * int64_t(_10en[Precision + 308]));
				// num0_8[i] -= condition;
				if (Precision > 0)
					num0_8[i] += '0' + '.' * (1 << 8);
				else
					num0_8[i] += '0';

				// num0_rest_8[i] = _mm512_cvtpd_epi64(value_8[i] * _mm512_i64gather_pd(exponent_8[i], _10en, 8) +
				// 									  MAGIC_NUMBER - MAGIC_NUMBER);
				// _mm512_storeu_epi64(&num0123456[i * group],
				// 				   _mm512_cvtpd_epi64(value_8[i] * _mm512_i64gather_pd(exponent_8[i], _10en, 8) +
				// 									  MAGIC_NUMBER - MAGIC_NUMBER));
			}
		}
	}

	if (0)
		for (int i = 0; i < group_count; ++i)
		{
			for (int j = 0; j < group; ++j)
			{
				// num0[i * group + j] = int64_t((double)num0123456[i * group + j] * _10en[-Precision + 308]);
				// num123456[i * group + j] = num0123456[i * group + j] - num0[i * group + j] * int64_t(_10en[Precision + 308]);
				// if (num0123456[i * group + j] == int64_t(_10en[Precision + 1 + 308])) // branch 3
				// {
				// 	exponent[i * group + j] += 1;
				// 	num0[i * group + j] = 1;
				// }
				// buffer[i * group + j][index[i * group + j] + 0] = '0' + char(num0[i * group + j]);
				// if (Precision > 0)
				// 	buffer[i * group + j][index[i * group + j] + 1] = '.';
			}
			// avx512
			num0_8[i] = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(num0_rest_8[i]) * _10en[-Precision + 308]);

			num_rest_8[i] = num0_rest_8[i] - num0_8[i] * int64_t(_10en[Precision + 308]);

			// for(int j=0;j<group;++j){
			// 	buffer[i * group + j][index[i * group + j] + 0] = '0' + char(num0_8[i][j]);
			// 	if (Precision > 0)
			// 		buffer[i * group + j][index[i * group + j] + 1] = '.';
			// }
			if (Precision > 0)
				num0_8[i] += '0' + '.' * (1 << 8);
			else
				num0_8[i] += '0';

			//_mm512_store_epi64(&num0[i*group],num0_8[i]);

			// write num0
			//  		for (int j = 0; j < group; ++j)
			//  		{
			//  			if (Precision > 0)
			//  			{
			//  // buffer[i * group + j][index[i * group + j] + 0] = '0' + char(num0_8[i][j]);
			//  // buffer[i * group + j][index[i * group + j] + 1] = '.';
			//  #if 0
			//  					short *buffer_short_ptr = (short *)&buffer[i * group + j][index[i * group + j] + 0];
			//  					*buffer_short_ptr = '0' + char(num0_8[i][j]) + '.' * (1 << 8);
			//  #else
			//  				short *buffer_short_ptr = (short *)&buffer_s[every_start_pos[i * group + j] + 0];
			//  				*buffer_short_ptr = num0_8[i][j];
			//  #endif
			//  			}
			//  			else
			//  			{
			//  #if 0
			//  					buffer[i * group + j][index[i * group + j] + 0] = '0' + char(num0_8[i][j]);
			//  #else
			//  				buffer_s[every_start_pos[i * group + j] + 0] =  num0_8[i][j];
			//  #endif
			//  			}
			//  		}
		}
	else
	{

		for (int i = 0; i < group_count; ++i)
		{
			// avx512
			// num0_8[i] = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(num0_rest_8[i]) * _10en[-Precision + 308]);

			// num_rest_8[i] = num0_rest_8[i] - num0_8[i] * int64_t(_10en[Precision + 308]);

			// if(Precision>0)
			// 	num0_8[i] += '0' + '.' * (1 << 8);
			// else
			// 	num0_8[i] += '0';
			// }

			// __m512d temp1[group_count];
			// __m512d temp2[group_count];
			// __m512i temp3[group_count];
			// for(int i=0;i<group_count;++i){
			// 	temp1[i]=_mm512_cvtepi64_pd(num0_rest_8[i]);
			// }
			// for(int i=0;i<group_count;++i){
			// 	temp2[i]=temp1[i]*_10en[-Precision + 308];
			// }
			// for(int i=0;i<group_count;++i){
			// 	num0_8[i]=_mm512_cvttpd_epi64(temp2[i]);
			// }
			// for(int i=0;i<group_count;++i){
			// 	if(Precision>0)
			// 	num0_8[i] += '0' + '.' * (1 << 8);
			// else
			// 	num0_8[i] += '0';
			// }
		}
	}

	// write num0
	for (int i = 0; i < group_count; i++)
	{
		for (int j = 0; j < group; ++j)
		{
			if (Precision > 0)
			{
// buffer[i * group + j][index[i * group + j] + 0] = '0' + char(num0_8[i][j]);
// buffer[i * group + j][index[i * group + j] + 1] = '.';
#if 0
					short *buffer_short_ptr = (short *)&buffer[i * group + j][index[i * group + j] + 0];
					*buffer_short_ptr = '0' + char(num0_8[i][j]) + '.' * (1 << 8);
#else
				short *buffer_short_ptr = (short *)&buffer_s[every_start_pos[i * group + j] + 0];
				*buffer_short_ptr = num0_8[i][j];
#endif
			}
			else
			{
#if 0
				buffer[i * group + j][index[i * group + j] + 0] = '0' + char(num0_8[i][j]);
#else
				buffer_s[every_start_pos[i * group + j] + 0] = num0_8[i][j];
#endif
			}
		}
	}
	// 写入小数点后Precision位。
	const int frac_div_2 = Precision / 2; // Precision
	const int frac_rest = Precision % 2;  // 1 or 0
	if (1)
	{
		// const int frac_div_2 = Precision / 2; // Precision
		// const int frac_rest = Precision % 2;  // 1 or 0
		for (int i = 0; i < group_count; ++i)
		{
			for (int j = 0; j < group; ++j)
			{
				// short *buffer_short_ptr = (short *)&buffer[i * group + j][index[i * group + j] + 1+(Precision > 0) + frac_rest];
				// for (int k = 0; k < frac_div_2; ++k)
				// {
				// 	int tmp_num_frac = num123456[i * group + j] - int64_t(num123456[i * group + j] * 0.01) * 100;
				// 	buffer_short_ptr[frac_div_2 - k - 1] = short_array[tmp_num_frac]; // loop vector
				// 	num123456[i * group + j] = int64_t(num123456[i * group + j] * 0.01);
				// }
				// if (frac_rest == 1)
				// 	buffer[i * group + j][(index[i * group + j]++) + 1+(Precision > 0)] = num123456[i * group + j] + '0';
				// index[i * group + j] += frac_div_2 * 2 + 1+(Precision > 0); // loop vector
			}
			// int tmp_num_frac = num123456 - int64_t(num123456 * 0.01) * 100;
			// num123456 = int64_t(num123456 * 0.01) - (tmp_num_frac < 0);
			// tmp_num_frac = (tmp_num_frac < 0) ? tmp_num_frac + 100 : tmp_num_frac;
			// buffer_short_ptr[frac_div_2 - 0 - 1] = short_array[tmp_num_frac];

			__m512i tmp_value_8 = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(num_rest_8[i]) * 0.01);
			__m512i tmp_num_frac_8 = num_rest_8[i] - (tmp_value_8 * 100);
			num_rest_8[i] = tmp_value_8 - (1 + (tmp_num_frac_8 >= 0));
			tmp_num_frac_8 = (1 + (tmp_num_frac_8 >= 0)) ? tmp_num_frac_8 + 100 : tmp_num_frac_8;
			if (t == 1)
			{
				for (int j = 0; j < group; ++j)
				{
					// printf("num_rest_8[%d][%d]=%lld ",i,j,num_rest_8[i][j]);
					// printf("tmp_num_frac_8[%d][%d]=%lld\n",i,j,tmp_num_frac_8[j]);
				}
			}
			for (int j = 0; j < group; ++j)
			{
#if 0
						short *buffer_short_ptr = (short *)&buffer[i * group + j][index[i * group + j] + 1 + (Precision > 0) + frac_rest];
						buffer_short_ptr[frac_div_2 - k - 1] = short_array[tmp_num_frac_8[j]];
#else
				short *buffer_short_ptr = (short *)&buffer_s[every_start_pos[i * group + j] + 1 + (Precision > 0) + frac_rest];
				buffer_short_ptr[frac_div_2 - 0 - 1] = short_array[tmp_num_frac_8[j]];
#endif
			}

			// avx512
			for (int k = 1; k < frac_div_2; k++)
			{
				__m512i tmp_value_8 = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(num_rest_8[i]) * 0.01);
				__m512i tmp_num_frac_8 = num_rest_8[i] - (tmp_value_8 * 100);
				for (int j = 0; j < group; j++)
				{
#if 0
						short *buffer_short_ptr = (short *)&buffer[i * group + j][index[i * group + j] + 1 + (Precision > 0) + frac_rest];
						buffer_short_ptr[frac_div_2 - k - 1] = short_array[tmp_num_frac_8[j]];
#else
					short *buffer_short_ptr = (short *)&buffer_s[every_start_pos[i * group + j] + 1 + (Precision > 0) + frac_rest];
					buffer_short_ptr[frac_div_2 - k - 1] = short_array[tmp_num_frac_8[j]];
#endif
				}
				num_rest_8[i] = tmp_value_8;
			}

			if (frac_rest == 1)
			{
				num_rest_8[i] += '0';
				for (int j = 0; j < group; j++)
				{
#if 0
						buffer[i * group + j][(index[i * group + j]) + 1 + (Precision > 0)] = num_rest_8[i][j] + '0';
#else
					buffer_s[(every_start_pos[i * group + j]) + 1 + (Precision > 0)] = num_rest_8[i][j];
#endif
				}
				// index[i * group + j] += frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1); // loop vector
			}
		}
	}
	else
	{
		if (Precision == 16)
		{
			__m512i num0_7[group_count] = {_mm512_set1_epi64(0)}, num8_15[group_count] = {_mm512_set1_epi64(0)};
			for (int i = 0; i < group_count; ++i)
				num0_7[i] = num8_15[i] = _mm512_set1_epi64(0);
			for (int i = 0; i < group_count; ++i)
			{
				// avx512
				for (int k = 0; k < frac_div_2 / 2; k++)
				{
					__m512i tmp_value_8 = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(num_rest_8[i]) * 0.01);
					__m512i tmp_num_frac_8 = num_rest_8[i] - (tmp_value_8 * 100);
					for (int j = 0; j < group; j++)
					{
						// short *buffer_short_ptr = (short *)&buffer_s[every_start_pos[i * group + j] + 1 + (Precision > 0) + frac_rest];
						// buffer_short_ptr[frac_div_2 - k - 1] = short_array[tmp_num_frac_8[j]];
						num8_15[i] = (num8_15[i] << 16) | short_array[tmp_num_frac_8[j]];
					}
					num_rest_8[i] = tmp_value_8;
				}
				for (int k = frac_div_2 / 2; k < frac_div_2; k++)
				{
					__m512i tmp_value_8 = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(num_rest_8[i]) * 0.01);
					__m512i tmp_num_frac_8 = num_rest_8[i] - (tmp_value_8 * 100);
					for (int j = 0; j < group; j++)
					{
						// short *buffer_short_ptr = (short *)&buffer_s[every_start_pos[i * group + j] + 1 + (Precision > 0) + frac_rest];
						// buffer_short_ptr[frac_div_2 - k - 1] = short_array[tmp_num_frac_8[j]];
						num0_7[i] = (num0_7[i] << 16) | short_array[tmp_num_frac_8[j]];
					}
					num_rest_8[i] = tmp_value_8;
				}
				for (int j = 0; j < group; ++j)
				{
					*(int64_t *)&buffer_s[every_start_pos[i * group + j] + 1 + (Precision > 0) + frac_rest] = num0_7[i][j];
					*(int64_t *)&buffer_s[every_start_pos[i * group + j] + 1 + (Precision > 0) + frac_rest + 8] = num8_15[i][j];
				}
			}
		}
	}

	if (1)
		for (int i = 0; i < group_count; ++i)
		{
			//__m512i exponent_abs_8 = _mm512_abs_epi64(exponent_8[i]);
			for (int j = 0; j < group; ++j)
			{
				int exponent_abs = abs(exponent[i * group + j]);

				// short *buffer_short_ptr = (short *)&buffer[i * group + j][index[i * group + j]];
				// *buffer_short_ptr = exponent[i * group + j] < 0 ? short('-' * 256 + 'e') : short('+' * 256 + 'e');

				if (exponent_abs < 100) [[likely]] // branch 3
				{
#if 0
				// short *buffer_short_ptr = (short *)&buffer[i * group + j][index[i * group + j] + 2];
				// *buffer_short_ptr = short_array[exponent_abs];
				// index[i * group + j] += 2 + 2;
				int *buffer_int_ptr = (int *)&buffer[i * group + j][index[i * group + j] + frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1)];
				// *buffer_int_ptr = (exponent[i * group + j] < 0 ? short('-' * 256 + 'e') : short('+' * 256 + 'e')  ) +
				// 				  short_array[exponent_abs] * (1<<16);
				*buffer_int_ptr = (exponent[i * group + j] < 0 ? short('-' * 256 + 'e') : short('+' * 256 + 'e')) +
								  write_array[exponent_abs];
				//*buffer_int_ptr = write_array[exponent_abs*2+exponent[i * group + j] < 0];

				index[i * group + j] += frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1) + 2 + 2;
#else
					int *buffer_int_ptr = (int *)&buffer_s[every_start_pos[i * group + j] + frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1)];
					// *buffer_int_ptr = (exponent[i * group + j] < 0 ? short('-' * 256 + 'e') : short('+' * 256 + 'e')  ) +
					// 				  short_array[exponent_abs] * (1<<16);
					*buffer_int_ptr = (exponent[i * group + j] < 0 ? short('-' * 256 + 'e') : short('+' * 256 + 'e')) +
									  write_array[exponent_abs];
					//*buffer_int_ptr = write_array[exponent_abs*2+exponent[i * group + j] < 0];

					every_start_pos[i * group + j] += frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1) + 2 + 2;

#endif
				}
				else
				{
// if (t == 1)
// 	printf("exponent_abs=%d exponent[%d]=%d\n", exponent_abs, j, exponent[i * group + j]);
#if 0
				short *buffer_short_ptr = (short *)&buffer[i * group + j][index[i * group + j] + frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1)];
				*buffer_short_ptr = exponent[i * group + j] < 0 ? short('-' * 256 + 'e') : short('+' * 256 + 'e');

				buffer[i * group + j][index[i * group + j] + 2 + frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1)] = int(exponent_abs * 0.01) + '0';

				buffer_short_ptr = (short *)&buffer[i * group + j][index[i * group + j] + 3 + frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1)];
				buffer_short_ptr[0] = short_array[exponent_abs - int(exponent_abs * 0.01) * 100];
				index[i * group + j] += frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1) + 3 + 2;
#else
					short *buffer_short_ptr = (short *)&buffer_s[every_start_pos[i * group + j] + frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1)];
					*buffer_short_ptr = exponent[i * group + j] < 0 ? short('-' * 256 + 'e') : short('+' * 256 + 'e');

					buffer_s[every_start_pos[i * group + j] + 2 + frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1)] = int(exponent_abs * 0.01) + '0';

					buffer_short_ptr = (short *)&buffer_s[every_start_pos[i * group + j] + 3 + frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1)];
					buffer_short_ptr[0] = short_array[exponent_abs - int(exponent_abs * 0.01) * 100];
					every_start_pos[i * group + j] += frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1) + 3 + 2;

#endif
				}
#if 0
				buffer[i * group + j][index[i * group + j]] = '\0';
#else
				buffer_s[every_start_pos[i * group + j]] = '\n'; // 以空格分割
#endif
			}

			// avx512
			//__m512i exponent_abs_8 = _mm512_abs_epi64(exponent_8[i]);
			//__m512i write_8 = exponent_8[i] < 0 ? short('-' * 256 + 'e') : short('+' * 256 + 'e');
			//_mm512_cmp_epi64_mask(exponent_8[i], __m512_set1_epi64(0), _MM_CMPINT_LT);
			//__m512i write_8 = _mm512_mask_blend_epi64( _mm512_cmp_epi64_mask(exponent_8[i], __m512_set1_epi64(0), _MM_CMPINT_LT) , __m512_set1_epi64('+' * 256 + 'e'), __m512_set1_epi64('-' * 256 + 'e'));
		}

	// int index_sum = 0;
	// for (int i = 0; i < All_double; ++i)
	// index_sum += (index[i] + 1);
	// return index_sum;
	// return every_start_pos[All_double - 1];
	return 0;
}

template <int t = 0, int Precision = 16, int All_double = 32, int Num_per_row = 3>
int my_dou_to_sci_avx512_pure(double *value, char **buffer, char *buffer_s = 0)
{
	const double r = 1.0 / log2(10.0); // 0.30102999566398120
	const double r2 = log2(10.0);
	static uint64_t call_num = 0; // 调用次数
	static double Row_per_num = 1.0 / (double)Num_per_row;
	// 为了提高速度，采用 avx512 一次性处理8*n个double数
	static const short short_array[100] = {12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640,
										   12337, 12593, 12849, 13105, 13361, 13617, 13873, 14129, 14385, 14641,
										   12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642,
										   12339, 12595, 12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643,
										   12340, 12596, 12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644,
										   12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645,
										   12342, 12598, 12854, 13110, 13366, 13622, 13878, 14134, 14390, 14646,
										   12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391, 14647,
										   12344, 12600, 12856, 13112, 13368, 13624, 13880, 14136, 14392, 14648,
										   12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649};
	// static const int write_array[100] = {808452096, 825229312, 842006528, 858783744, 875560960, 892338176, 909115392, 925892608, 942669824, 959447040,
	// 									 808517632, 825294848, 842072064, 858849280, 875626496, 892403712, 909180928, 925958144, 942735360, 959512576,
	// 									 808583168, 825360384, 842137600, 858914816, 875692032, 892469248, 909246464, 926023680, 942800896, 959578112,
	// 									 808648704, 825425920, 842203136, 858980352, 875757568, 892534784, 909312000, 926089216, 942866432, 959643648,
	// 									 808714240, 825491456, 842268672, 859045888, 875823104, 892600320, 909377536, 926154752, 942931968, 959709184,
	// 									 808779776, 825556992, 842334208, 859111424, 875888640, 892665856, 909443072, 926220288, 942997504, 959774720,
	// 									 808845312, 825622528, 842399744, 859176960, 875954176, 892731392, 909508608, 926285824, 943063040, 959840256,
	// 									 808910848, 825688064, 842465280, 859242496, 876019712, 892796928, 909574144, 926351360, 943128576, 959905792,
	// 									 808976384, 825753600, 842530816, 859308032, 876085248, 892862464, 909639680, 926416896, 943194112, 959971328,
	// 									 809041920, 825819136, 842596352, 859373568, 876150784, 892928000, 909705216, 926482432, 943259648, 960036864};
	const int group = 8;						// avx512 = 8 double
	const int group_count = All_double / group; // 16:2 24:3 32:4
	static __m512i index_8[group_count];
	__m512i index_mod_Num_per_row[group_count];
	const __m512i index_base = _mm512_set_epi64(8, 7, 6, 5, 4, 3, 2, 1);
	for (int i = 0; i < group_count; ++i)
	{
		index_8[i] = call_num * All_double + i * group + index_base;
		index_mod_Num_per_row[i] = index_8[i] - _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(index_8[i]) * Row_per_num) * Num_per_row;
	}
	call_num++;
	__m512d value_abs_d8[group_count];
	__m512i value_i8[group_count];
	__m512i value_abs_i8[group_count];
	__m512i ieee754_exp11_8[group_count];
	__m512i value_f_8[group_count];
	__m512i value_e_8[group_count];
	__m512i value_e2_8[group_count];
	//__m512i value_clz_8[group_count];
	__m512i value_e10_8[group_count];
	int64_t e10[All_double];
	__m512i every_length_8[group_count];
	int every_start_pos[All_double + 1]; // 第一个值为0
	every_start_pos[0] = 0;
	for (int i = 0; i < group_count; ++i)
	{
		value_i8[i] = _mm512_loadu_epi64(&value[i * group]);												// 以int64方式存储
		value_abs_d8[i] = __m512d(value_i8[i] & ((1ull << 63) - 1));										// 绝对值
		value_abs_i8[i] = __m512i(value_abs_d8[i]);															// 绝对值,int64
		ieee754_exp11_8[i] = _mm512_srli_epi64(value_abs_i8[i], 52);										// 右移52获取指数
		__m512i clz_8 = _mm512_lzcnt_epi64(value_abs_i8[i]);												// 计算前缀0的个数
		clz_8 = _mm512_max_epi64(clz_8, _mm512_set1_epi64(11));												// 与11对比取大
		__m512i value_exp_nz_8 = 1 + (ieee754_exp11_8[i] == 0);												// ieee754的exp是否非0
		value_f_8[i] = _mm512_sllv_epi64(value_abs_i8[i], clz_8) | (_mm512_slli_epi64(value_exp_nz_8, 63)); // 计算f
		value_e2_8[i] = ieee754_exp11_8[i] + 1 - value_exp_nz_8 - 1023 + 11 - clz_8;						// 计算e2
		value_e_8[i] = value_e2_8[i] - 63;																	// 计算e
	}

	for (int i = 0; i < group_count; ++i)
	{
		// __m512i _10en_index = (_mm512_cvttpd_epi64(_mm512_cvtepi64_pd(((__m512i(value_8[i]) >> 52)) - 1023) * r) + (value_8[i] < 1.0));
		// exponent_8[i] = (value_8[i] == 0.0) ? 0 : (_10en_index - ((value_8[i] >= _mm512_i64gather_pd(_10en_index, &_10en[325 + 16], 8)))); // value==0时 exponent=0;
		// _mm512_storeu_epi64(&exponent[i * group], exponent_8[i]);
		__m512i e10_temp = ((value_e2_8[i] * 78913) >> 18);
		// value_e10_8[i] = e10_temp + 1 + (value_abs_d8[i] < _mm512_i64gather_pd(e10_temp + 1 + 324, _10en, sizeof(double))) - 1 - (value_abs_i8[i] != 2);
		value_e10_8[i] = e10_temp + (value_abs_d8[i] < _mm512_i64gather_pd(e10_temp + 1 + 324, _10en, sizeof(double))) - (value_abs_i8[i] != 2);
		value_e10_8[i] = (value_abs_i8[i] == 0) ? 0 : value_e10_8[i];
		_mm512_storeu_epi64(&e10[i * group], value_e10_8[i]);

		every_length_8[i] = (1 + (__m512d(value_i8[i]) >= 0)) +								   /*value<0时有负号*/
							(1 + ((value_abs_d8[i] < 1e100) & (value_abs_d8[i] >= 1e-99))) + 2 /*exp>=100时为3,exp<100时为2*/
							+ (Precision > 0)												   /*小数点*/
							+ 1																   /*间隔空格个数*/
							+ 1																   /*小数点前一位*/
							+ Precision														   /*小数点后有几位*/
							+ 2;															   /* 'e+' or 'e-' */
	}
	for (int i = 0; i < group_count; ++i)//4
	{
		for (int j = 0; j < group; ++j)//8
		{
			every_start_pos[i * group + j + 1] = every_start_pos[i * group + j] + every_length_8[i][j]; // 计算前缀和
			buffer_s[every_start_pos[i * group + j]] = '-';
			// every_start_pos[i * group + j + 1] += (value[i*group+j]<0);
		}
	}
	__m512i num0_rest_8[group_count];
	__m512i num0_8[group_count];
	__m512i num_rest_8[group_count];
	for (int i = 0; i < group_count; ++i)
	{
		// compute value的f和e,获取10的-e10+Precision次方，相乘
		__m512i value_8i_f = value_f_8[i];
		__m512i value_8i_e = value_e_8[i];
		__m512i pow10_8_f = _mm512_i64gather_epi64(-value_e10_8[i] + 343 + Precision, powers_ten, sizeof(uint64_t));
		//__m512i pow10_8_e = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(-exponent_8[i] + Precision) * r2) - 63 - (1 + (-exponent_8[i] + Precision) <= 0);
		__m512i pow10_8_e = (((-value_e10_8[i] + Precision) * 1741647) >> 19) - 63;
		const uint64_t M32 = 0xFFFFFFFF;
		__m512i a = _mm512_srli_epi64(value_8i_f, 32);
		__m512i b = value_8i_f & M32;
		__m512i c = _mm512_srli_epi64(pow10_8_f, 32);
		__m512i d = pow10_8_f & M32;
		__m512i ac = _mm512_mul_epu32(a, c);
		//__m512i bd = _mm512_mul_epu32(b, d);
		__m512i ad = _mm512_mul_epu32(a, d);
		__m512i bc = _mm512_mul_epu32(b, c);
		__m512i hi = ac + _mm512_srli_epi64(ad, 32) + _mm512_srli_epi64(bc, 32);
		//__m512i lo = bd + (ad & M32) + (bc & M32);
		//__m512i res_f = hi + _mm512_srli_epi64(lo, 63);
		__m512i res_f = hi;
		__m512i res_e = value_8i_e + pow10_8_e + 64;
		__m512i add_num = _mm512_srlv_epi64(res_f, (-res_e - 1)) & 1;
		num0_rest_8[i] = _mm512_srlv_epi64(res_f, (-res_e)) + add_num;
		num0_8[i] = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(num0_rest_8[i]) * _10en[-Precision + 324]);
		num0_8[i] -= ((num0_rest_8[i] - num0_8[i] * int64_t(_10en[Precision + 324])) >= 0) + 1;
		num_rest_8[i] = (num0_rest_8[i] - num0_8[i] * int64_t(_10en[Precision + 324]));
		if (Precision > 0)
			num0_8[i] += '0' + '.' * (1 << 8);
		else
			num0_8[i] += '0';
	}
	// write num0
	for (int i = 0; i < group_count; i++)
	{
		for (int j = 0; j < group; ++j)
		{
			if (Precision > 0)
			{
				short *buffer_short_ptr = (short *)&buffer_s[every_start_pos[i * group + j] + (value[i * group + j] < 0)];
				*buffer_short_ptr = num0_8[i][j];
			}
			else
			{
				buffer_s[every_start_pos[i * group + j] + (value[i * group + j] < 0)] = num0_8[i][j];
			}
			every_start_pos[i * group + j] += (value[i * group + j] < 0);
		}
	}
	// 写入小数点后Precision位。
	const int frac_div_2 = Precision / 2; // Precision/2
	const int frac_rest = Precision % 2;  // 1 or 0
	{
		for (int i = 0; i < group_count; ++i)
		{
			__m512i tmp_value_8 = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(num_rest_8[i]) * 0.01);
			__m512i tmp_num_frac_8 = num_rest_8[i] - (tmp_value_8 * 100);
			num_rest_8[i] = tmp_value_8 - (1 + (tmp_num_frac_8 >= 0));
			tmp_num_frac_8 = (1 + (tmp_num_frac_8 >= 0)) ? tmp_num_frac_8 + 100 : tmp_num_frac_8;
			for (int j = 0; j < group; ++j)
			{
				short *buffer_short_ptr = (short *)&buffer_s[every_start_pos[i * group + j] + 1 + (Precision > 0) + frac_rest];
				buffer_short_ptr[frac_div_2 - 0 - 1] = short_array[tmp_num_frac_8[j]];
			}
			// avx512
			for (int k = 1; k < frac_div_2; k++)
			{
				__m512i tmp_value_8 = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(num_rest_8[i]) * 0.01);
				__m512i tmp_num_frac_8 = num_rest_8[i] - (tmp_value_8 * 100);
				for (int j = 0; j < group; j++)
				{
					short *buffer_short_ptr = (short *)&buffer_s[every_start_pos[i * group + j] + 1 + (Precision > 0) + frac_rest];
					buffer_short_ptr[frac_div_2 - k - 1] = short_array[tmp_num_frac_8[j]];
				}
				num_rest_8[i] = tmp_value_8;
			}
			if (frac_rest == 1)
			{
				num_rest_8[i] += '0';
				for (int j = 0; j < group; j++)
				{
					buffer_s[(every_start_pos[i * group + j]) + 1 + (Precision > 0)] = num_rest_8[i][j];
				}
			}
		}
	}

	// write e10
	for (int i = 0; i < group_count; ++i)
	{
		for (int j = 0; j < group; ++j)
		{
			int e10_abs = abs(e10[i * group + j]);

			// short *buffer_short_ptr = (short *)&buffer[i * group + j][index[i * group + j]];
			// *buffer_short_ptr = exponent[i * group + j] < 0 ? short('-' * 256 + 'e') : short('+' * 256 + 'e');
			if (e10_abs < 100)
			{
				int *buffer_int_ptr = (int *)&buffer_s[every_start_pos[i * group + j] + frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1)];
				*buffer_int_ptr = (e10[i * group + j] < 0 ? short('-' * 256 + 'e') : short('+' * 256 + 'e')  ) |
								  (short_array[e10_abs] << 16);
				// *buffer_int_ptr = (e10[i * group + j] < 0 ? short('-' * 256 + 'e') : short('+' * 256 + 'e')) +
				// 				  write_array[e10_abs];
				every_start_pos[i * group + j] += frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1) + 2 + 2;
			}
			else
			{
				short *buffer_short_ptr = (short *)&buffer_s[every_start_pos[i * group + j] + frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1)];
				*buffer_short_ptr = e10[i * group + j] < 0 ? short('-' * 256 + 'e') : short('+' * 256 + 'e');

				buffer_s[every_start_pos[i * group + j] + 2 + frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1)] = ((e10_abs * 82) >> 13) + '0';

				buffer_short_ptr = (short *)&buffer_s[every_start_pos[i * group + j] + 3 + frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1)];
				buffer_short_ptr[0] = short_array[e10_abs - ((e10_abs * 82) >> 13) * 100];
				every_start_pos[i * group + j] += frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1) + 3 + 2;
			}
			//buffer_s[every_start_pos[i * group + j]] = index_mod_Num_per_row[i][j] ? ' ' : '\n'; // 以空格或换行符分割
			buffer_s[every_start_pos[i * group + j]] = '\n'; // 以空格或换行符分割
		}
	}
	// int index_sum = 0;
	// for (int i = 0; i < All_double; ++i)
	// index_sum += (index[i] + 1);
	// return index_sum;
	return every_start_pos[All_double];
	// return 0;
}

template <int t = 0, int Precision = 6>
int my_dou_to_sci(double value, char *buffer)
{
	const double r2 = log2(10);
	const double s = 2.2204460492503131; // 1e16/2**52
	const double s2 = s * pow(2.0, -52);
	// const double s=4.4408920985006262;
	// const double s =   1.1102230246251565;
	// const double s = 11.102230246251565;
	if (t == 1)
	{
		// printf("\n");
		print_double(value);
	}
	static const short short_array[100] = {12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640,
										   12337, 12593, 12849, 13105, 13361, 13617, 13873, 14129, 14385, 14641,
										   12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642,
										   12339, 12595, 12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643,
										   12340, 12596, 12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644,
										   12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645,
										   12342, 12598, 12854, 13110, 13366, 13622, 13878, 14134, 14390, 14646,
										   12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391, 14647,
										   12344, 12600, 12856, 13112, 13368, 13624, 13880, 14136, 14392, 14648,
										   12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649};
	int index = 0;
	int is_negative = value < 0.0;
	buffer[0] = '-';
	if (value < 0) // 1 branch
	{
		// buffer[index++] = '-';
		// value = -value;
	}
	// buffer[index] = value<0 ? '-' : '+';
	index = is_negative;
	value = std::fabs(value);
	DiyFp value_diyfp = DiyFp(value);
	// int exponent = getb(value);
	const double r = log10(2.0); // 0.30102999566398120;
	// int exponent = static_cast<int>(((*(reinterpret_cast<uint64_t *>(&value)) >> 52) & 0x7FF) - 1023) * r; // 5 operation
	int ieee754_exp = int((((*(uint64_t *)(&value)) >> 52) & 0x7FF) - 1023);
	int clz = 11;
	if (ieee754_exp == -1023)
	{
		// 计算前缀0的个数
		clz = __builtin_clzll(*(uint64_t *)(&value));
		ieee754_exp -= (clz - 11);
		if (t == 1)
		{
			printf("clz=%d\n", clz);
			printf("ieee754_exp=%d\n", ieee754_exp);
		}
	}
	value_diyfp.normalize(clz);
	int exponent; // = ieee754_exp * r;
	if (t == 1)
	{
		printf("exponent=%d\n", exponent);
	}
	// int condition = (value >= 1.0);
	int e10 = ((ieee754_exp * 78913) >> 18) + (value >= _10en[((ieee754_exp * 78913) >> 18) + 324 + 1]) - (value == 1e-323);
	// int b = (exponent + condition) - (value < _10en[(exponent + condition) + 324]) - (value == 1e-323);
	int b = e10;
	int exponent_final = (value == 0.0 ? 0 : b); // 处理特殊值0

	// int cmp_condition = 0;
	// if (exponent_final != exponent)
	// {
	// 	cmp_condition = 1;
	// }
	exponent = exponent_final;

	if (t == 1)
	{
		printf("exponent=%d\n", exponent);
	}
	// DiyFp(powers_ten[343+(-exponent)], powers_ten_e[343+(-exponent)]);
	// DiyFp mul_result = value_diyfp * DiyFp(powers_ten[343 + (-exponent) + 16], powers_ten_e[343 + (-exponent) + 16]);
	// DiyFp mul_result = value_diyfp * DiyFp(powers_ten[343 + (-exponent) + 16], int((-exponent+16)*r2)-63-((-exponent+16)<0) );
	DiyFp mul_result = value_diyfp * DiyFp(powers_ten[343 + (-exponent) + Precision], (((-exponent + Precision) * 1741647) >> 19) - 63); // log2(10)
	// int((-exponent)*r2)-63-(-exponent<0);

	if (t == 1)
	{
		printf("mul_result.f=%llx\n", mul_result.f);
		printf("mul_result.e=%d\n", mul_result.e);
	}
	// if(num<1.0)num_mul=10.0;
	// if(num>=10.0)num_mul=0.1;

	// double num = std::fabs(value) * _10en[-exponent + 308];
	// double value_mul = ;
	double tmp_num; //
	// tmp_num = num * _10en[Precision + 308];
	// if (num < 1.0)
	// 	tmp_num *= 10.0;
	// if (num >= 10.0)
	// 	tmp_num *= 0.1;

	// 乘法
	// if (exponent <= (-308 + (Precision - 1))) [[unlikely]] // 1% 概率,随机数的情况下 branch 2
	// {													   //-303      branch 2
	// 	tmp_num = value * _10en[-(exponent - (-308 + Precision)) + 308] * 1e308;
	// }
	// else
	// {
	// 	tmp_num = value * _10en[(-exponent) + Precision + 308];
	// }

	// tmp_num = value * _10en[(-exponent) + Precision + 308];
	// if (exponent <= (-308 + (Precision - 1)))
	// 	tmp_num *= 1e308;

	//;

	// 除法
	//  if( exponent - (Precision-1) <= -308){
	//  	//tmp_num = value / _10en[(exponent) + Precision + 308];
	//  	tmp_num = value / _10en[(exponent - (-308 + Precision)) + 308] / 1e-308;
	//  }else{
	//  	tmp_num = value / _10en[(exponent) - Precision + 308];
	//  }

	if (t == 1)
	{
		// printf("tmp_num = %.16le\n", tmp_num);
		// print_double(tmp_num);
		// print_double(_10en[(-exponent) + Precision + 308]);
		// // print_double(tmp_num + MAGIC_NUMBER - MAGIC_NUMBER);

		// double num1 = tmp_num;
		// double num2 = tmp_num + MAGIC_NUMBER - MAGIC_NUMBER;
		// int num3 = *(uint64_t *)&num1 - *(uint64_t *)&num2;
		// int add_value = num3 >> (51 - getexponent(tmp_num));

		// // printf("num3 = %d\n", num3);
		// const double r = 1.0 / log2(10.0);
		// double value = num3 < (1 << int(51 - getexponent(tmp_num)));
		// printf("cmp = %d\n", (1 << int(51 - getexponent(tmp_num))));
		// printf("value = %d\n", num3 >> (51 - getexponent(tmp_num)));
		//  printf("value = %lf\n",value);

		// print_double(tmp_num);
	}

	int64_t num0123456; //= tmp_num + MAGIC_NUMBER - MAGIC_NUMBER;

	if (Precision <= 14)
	{
		const double MAGIC_NUMBER = 1.5 * (1ll << 52);
		num0123456 = int64_t(tmp_num + MAGIC_NUMBER - MAGIC_NUMBER);
	}
	else if (Precision == 15)
	{
		// const double MAGIC_NUMBER = tmp_num < double(1ll<<51) ? double(1.5*(1ll<<52)) : double(1ll<<52);
		// const double MAGIC_NUMBER = 1.5*(1ll<<52);
		const double MAGIC_NUMBER = 1 * (1ll << 52);
		num0123456 = int64_t(tmp_num + MAGIC_NUMBER - MAGIC_NUMBER);

		// num0123456 = int64_t(tmp_num);
	}
	else if (Precision == 16)
	{
		// const double MAGIC_NUMBER = 1*(1ll<<52);
		// num0123456 = int64_t(tmp_num + MAGIC_NUMBER - MAGIC_NUMBER);

		// num0123456 = int64_t(tmp_num);
		// num0123456 = int64_t(4e16) + int64_t(  (((*(int64_t *)&value) & ((1ll << 52) - 1))) * (s)) * 4 ; //+   int64_t((((*(int64_t *)&value) & ((1ll << 52) - 1))) * s2);
		// num0123456 = (value * double(1<<14)) * double(152587890625)
		// num0123456 = int64_t((value * double(1<<12)) * double(152587890625) ) * 16 +
		//((value * double(1<<12)) * double(152587890625) - int64_t((value * double(1<<12)) * double(152587890625) )) * 16;
		// num0123456 = int64_t((value  * double(152587890625/5) ) * double(1<<15)) * 10 + int64_t(value);
		// num0123456 = start + value_frac * scale;
		// value - *(uint64_t*)&value & 0xFFF0000000000000
#if 1
		// auto frac = getfrac(value);
		// double value_frac_mul = all_info[getexponent(value) + 1022].scale1;
		// if (cmp_condition)
		// 	value_frac_mul = all_info[getexponent(value) + 1022].scale2;
		// auto frac_mul = getfrac(value_frac_mul);
		// int num_exp = getexponent(value_frac_mul);
		// //frac_mul <<= getexponent(value_frac_mul);
		// uint64_t hi, lo;
		// mult64to128(frac, frac_mul, &hi, &lo);
		// //num0123456 = ((hi & ((1ll << 52) - 1)) << 12) + (lo >> 52) + (((lo & ((1ll << 52) - 1)) >= ((1ll << 51) - 1)));
		// //num0123456 = ((hi & ((1ll << 52) - 1)) << (12+num_exp)) + (lo >> (52-num_exp)) + (((lo & ((1ll << (52-num_exp)) - 1)) >= ((1ll << (51-num_exp)) - 1)));
		// num0123456 = ((hi & ((1ll << 52) - 1)) << (12+num_exp)) + (lo >> (52-num_exp)) ;

#else
		// start + frac * scale
		//  num0123456 *= 4; 10001110000110111100100110111111000001000000000000000=5e15

		auto start_num = array[getexponent(value) + 1022];
		auto frac = getfracnot1(value);
		double value_frac_mul = all_info[getexponent(value) + 1022].scale1;
		if (cmp_condition)
		{
			value_frac_mul = all_info[getexponent(value) + 1022].scale2;
			frac -= (*(uint64_t *)&_10en[exponent + 324] & ((1ll << 52) - 1));
			start_num = int64_t(1e16);
		}
		auto frac_mul = getfrac(value_frac_mul);
		// frac_mul <<= getexponent(value_frac_mul);
		int num_exp = getexponent(value_frac_mul);
		uint64_t hi, lo;
		mult64to128(frac, frac_mul, &hi, &lo);
		// num0123456 = start_num + (((hi & ((1ll << 52) - 1)) << 12) + (lo >> 52) + (((lo & ((1ll << 52) - 1)) >= ((1ll << 51) - 1))));
		// num0123456 = start_num + (((hi & ((1ll << (52+0)) - 1)) << (12+num_exp)) + (lo >> (52-num_exp)) + (((lo & ((1ll << 52) - 1)) >= ((1ll << 51) - 1))));
		num0123456 = start_num + (((hi & ((1ll << (52 + 0)) - 1)) << (12 + num_exp)) + (lo >> (52 - num_exp)));

		if (t == 1)
		{
			printf("start_num=%lld,n*scale=%lld,num_exp=%d\n", start_num, (((hi & ((1ll << (52 + 0)) - 1)) << (12 + num_exp)) + (lo >> (52 - num_exp))), num_exp);
		}
		// num0123456 = start_num + (((hi & ((1ll << 52) - 1)) << 12) + (lo >> 52) );
#endif
		// uint64_t add_num = ( (mul_result.f & ( (1ull<<(-mul_result.e)) -1) ) >= ( (1ull<<(-mul_result.e-1)) - 1 ));
		uint64_t add_num = ((mul_result.f >> (-mul_result.e - 1)) & 1);
		if (t == 1)
		{
			uint64_t tmp_num = mul_result.f >> (-mul_result.e);
			printf("tmp_num=%lld\n", tmp_num);
			printf("rest_num=%llx\n", (mul_result.f & ((1ull << (-mul_result.e)) - 1)));
			printf("add_num=%d\n", add_num);
		}
		num0123456 = (mul_result.f >> (-mul_result.e)) + add_num;
	}
	double magic_number = 1.5 * (1ll << 52);
	if (t == 1)
	{
		printf("getexponent=%d\n", getexponent(tmp_num));
	}

	// int64_t num0123456 = tmp_num ;
	// int64_t num0123456 = tmp_num + MAGIC_NUMBER - MAGIC_NUMBER;
	// int64_t num0123456 = llabs(  int64_t(tmp_num + magic_number - magic_number) );
	// int64_t num0123456 = llabs(  int64_t(tmp_num+magic_number-magic_number) );

	// int64_t num0123456_2 = llabs(int64_t(tmp_num));
	if (t == 1)
	{
		printf("num0123456=%lld\n", num0123456);
		// printf("num0123456_2=%lld\n",num0123456_2);
	}
	// num0123456 += 1;
	//  double num1=tmp_num ;
	//  double num2=tmp_num+MAGIC_NUMBER-MAGIC_NUMBER;
	//  int num3=*(uint64_t*)&num1 - *(uint64_t*)&num2;
	//  int num3_abs=abs(num3);
	//  int add_value ;//= num3>>(51-getexponent(tmp_num));
	//  if(num3 >=  (1<<int(51-getexponent(tmp_num))))add_value=1;
	//  else if(num3 <=  -(1<<int(51-getexponent(tmp_num))))add_value=-1;
	// num0123456 += add_value;
	if (t == 1)
	{
		// printf("add_value=%d\n",add_value);
	}

	// int64_t num0 = int64_t((double)num0123456 * _10en[-Precision + 324]);
	// int64_t num123456 = num0123456 - num0 * int64_t(_10en[Precision + 324]);
	// if(num123456 < 0){
	// 	num0--;
	// 	num123456 += int64_t(_10en[Precision + 324]);
	// }

	int64_t num01 = int64_t((double)num0123456 * _10en[-Precision + 1 + 324]); // 1e-15
	int64_t num2_rest = num0123456 - num01 * int64_t(_10en[Precision - 1 + 324]);
	if (num2_rest < 0)
	{
		num01--;
		num2_rest += int64_t(_10en[Precision - 1 + 324]);
	}
	int num0 = (num01 * 103) >> 10; // num01/10;
	int num1 = num01 - num0 * 10;

	// int64_t num123456 =  (*(int64_t*)&value & ((1ll << 52)-1) ) * s;

	// if(num0123456 == 10000000)
	// if (num0123456 == int64_t(_10en[Precision + 1 + 308]))
	{
		// exponent += 1;
		// num0 = 1;
		// printf("value=%.16le exponent=%d\n",value,exponent);
	}
	// exponent += num0123456 == int64_t(_10en[Precision + 1 + 308]);
	// num0 = num0123456 == int64_t(_10en[Precision + 1 + 308]) ? 1 : num0;

	if (t == 1)
	{
		printf("num0=%d\n", num0);
		printf("num1=%d\n", num1);
		printf("num2_rest=%lld\n", num2_rest);
	}
	// printf("num123456 = %lld\n", num123456);

	buffer[index + 0] = '0' + char(num0);

	if (Precision > 0)
		buffer[index + 1] = '.';
	// double num123456_double = num123456;
	const int frac_div_2 = Precision / 2; // Precision
	const int frac_rest = Precision % 2;  // 1 or 0
	char num_frac[frac_div_2];
	short ascii_num_frac[frac_div_2];
	char num_rest;
	// short *buffer_short_ptr = (short *)&buffer[index];

	// 这种方法慢，已被注释
	//  if (Precision <= 14)
	//  {
	//  	short *buffer_short_ptr = (short *)&buffer[index+2];
	//  	for (int i = 0; i < frac_div_2; ++i)
	//  	{
	//  		int tmp_num_frac = num123456 * _10en[-(Precision - 2 * i - 2) + 308];
	//  		// num_frac[i] = num123456 * _10en[ -(Precision-2*i-2) + 308];
	//  		//  ascii_num_frac[i] = short_array[num_frac[i]];
	//  		//  buffer_short_ptr[i] = ascii_num_frac[i] ;
	//  		buffer_short_ptr[i] = short_array[tmp_num_frac];
	//  		num123456 -= tmp_num_frac * _10en[(Precision - 2 * i - 2) + 308];
	//  	}
	//  	index += frac_div_2 * 2 + 2;
	//  	if (frac_rest == 1)
	//  		buffer[index++] = num123456 + '0';
	//  }
	//  else
	if (1)
	{
		short *buffer_short_ptr = (short *)&buffer[index + 1 + (Precision > 0) + frac_rest];

		// const __m512d m512d = _mm512_set_pd(1e-16,1e-14,1e-12,1e-10,1e-8,1e-6,1e-4,1e-2);
		const __m512d m512d = _mm512_set_pd(1e-2, 1e-4, 1e-6, 1e-8, 1e-10, 1e-12, 1e-14, 1e-16);
		// const __m512i m512i = _mm512_set_epi64(1e16,1e14,1e12,1e10,1e8,1e6,1e4,1e2);
		const __m512i m512i = _mm512_set_epi64(1e2, 1e4, 1e6, 1e8, 1e10, 1e12, 1e14, 1e16);
		// const __m512d m512d2 = _mm512_set_pd(1e-14,1e-12,1e-10,1e-8,1e-6,1e-4,1e-2,1e0);
		const __m512d m512d2 = _mm512_set_pd(1e0, 1e-2, 1e-4, 1e-6, 1e-8, 1e-10, 1e-12, 1e-14);

		__m512d num2_rest_d = _mm512_set1_pd((double)num2_rest);
		__m512i num2_rest_i = _mm512_set1_epi64(num2_rest);

		__m512i result_8 = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(num2_rest_i - _mm512_cvttpd_epi64(num2_rest_d * m512d) * m512i) * m512d2);

		int num12 = num1 * 10 + result_8[0];
		if (t == 1)
		{
			printf("result_8[%d]=%d num12=%d ", 0, result_8[0], num12);
		}
		buffer_short_ptr[0] = short_array[num12];
		for (int i = 1; i < frac_div_2; ++i)
		{
			buffer_short_ptr[i] = short_array[result_8[i]]; // 1-7
			if (t == 1)
			{
				printf("result_8[%d]=%d ", i, result_8[i]);
			}
		}

#if 0
		int tmp_num_frac = num123456 - int64_t(num123456 * 0.01) * 100;
		num123456 = int64_t(num123456 * 0.01) - (tmp_num_frac < 0);
		tmp_num_frac = (tmp_num_frac < 0) ? tmp_num_frac + 100 : tmp_num_frac;
		buffer_short_ptr[frac_div_2 - 0 - 1] = short_array[tmp_num_frac];


		for (int i = 1; i < frac_div_2; ++i)
		{
			int tmp_num_frac = num123456 - int64_t(num123456 * 0.01) * 100;
			buffer_short_ptr[frac_div_2 - i - 1] = short_array[tmp_num_frac];
			num123456 = int64_t(num123456 * 0.01);
		}
#endif

		if (frac_rest == 1)
		{
			// buffer[(index) + 1 + (Precision > 0)] = num123456 + '0';
		}

		index += frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1);
	}

	// if (frac_rest == 1)
	// {
	// 	buffer[index++] = num123456 + '0';
	// }else{
	// 	index += frac_div_2 * 2;
	// }

	// num12_ = short_array[num_frac[0]];
	// num34_ = short_array[num_frac[1]];
	// num56_ = short_array[num_frac[2]];
	// num12_=ascii_num_frac[0];
	// num34_=ascii_num_frac[1];
	// num56_=ascii_num_frac[2];
	// buffer[]

	// buffer[index+0] = 'e';
	// //int exponent_tag = 2 * (exponent < 0) + int('+'); // '-' or '+
	// buffer[index+1] = exponent < 0 ? '-' : '+';
	int exponent_abs = abs(exponent);
	short *buffer_short_ptr = (short *)&buffer[index];
	*buffer_short_ptr = exponent < 0 ? short('-' * 256 + 'e') : short('+' * 256 + 'e');
	if (exponent_abs < 100) // branch 3
	{
		short *buffer_short_ptr = (short *)&buffer[index + 2];
		*buffer_short_ptr = short_array[exponent_abs];
		index += 2 + 2;
	}
	else
	{
		buffer[index + 2] = int(exponent_abs * 0.01) + '0';
		short *buffer_short_ptr = (short *)&buffer[index + 3];
		buffer_short_ptr[0] = short_array[exponent_abs - int(exponent_abs * 0.01) * 100];
		index += 3 + 2;
	}
	if (t == 1)
	{
		printf("num0=%d num0123456=%lld exponent=%d\n", num0, num0123456, exponent);
	}
	buffer[index] = '\0';
	return index + 1;
}

template <int Precision = 16>
int my_dou_to_sci_pure(double value, char *buffer)
{
	static const short short_array[100] = {12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640,
										   12337, 12593, 12849, 13105, 13361, 13617, 13873, 14129, 14385, 14641,
										   12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642,
										   12339, 12595, 12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643,
										   12340, 12596, 12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644,
										   12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645,
										   12342, 12598, 12854, 13110, 13366, 13622, 13878, 14134, 14390, 14646,
										   12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391, 14647,
										   12344, 12600, 12856, 13112, 13368, 13624, 13880, 14136, 14392, 14648,
										   12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649};
	// int index = 0;
	int is_negative = value < 0.0;
	buffer[0] = '-';
	int index = is_negative;
	value = std::fabs(value);
	uint64_t value_u64 = *(uint64_t *)&value;
	// DiyFp value_diyfp = DiyFp(value);
	int ieee754_exp11 = (value_u64 >> 52);
	uint64_t f;
	int e;
	int e2;
	// uint64_t f = (value_u64 & ((1ull << 52) - 1)) | ((ieee754_exp11!=0)?(1ull << 52):0);
	// int e = ieee754_exp11 - 1023 - 52 + (ieee754_exp11==0) ;
	// int ieee754_exp = ieee754_exp11 - 1023;
	// int clz;
	if (ieee754_exp11 == 0)
	{
		int clz = __builtin_clzll(value_u64); // 计算前缀0的个数
		e2 = -1022 - (clz - 11);
		f = (value_u64) << clz;
		e = -1074 - clz;
	}
	else
	{
		f = ((value_u64 & ((1ull << 52) - 1)) | (1ull << 52)) << 11;
		e = ieee754_exp11 - 1023 - 52 - 11;
		e2 = ieee754_exp11 - 1023;
	}
	// clz = __builtin_clzll(value_u64);
	// clz = std::max(11,clz);
	// ieee754_exp-=(clz-11);
	// value_diyfp.normalize(clz);
	int e10 = ((e2 * 78913) >> 18) + (value >= _10en[((e2 * 78913) >> 18) + 324 + 1]) - (value_u64 == 2);

	int pow10_e = (((-e10 + Precision) * 1741647) >> 19) - 63;
	// int e10_abs = abs(e10);
	//  DiyFp mul_result = value_diyfp * DiyFp(powers_ten[343 + (-e10) + Precision], (((-e10 + Precision)*1741647) >> 19) - 63 );//log2(10)
	uint64_t pow10_f = powers_ten[343 + (-e10) + Precision];
	e10 = (value_u64 == 0 ? 0 : e10); // 处理特殊值0

	//__umul128();
	// mulhi(f,pow10_f);

	// const uint64_t M32 = 0xFFFFFFFF;
	// const uint64_t a = f >> 32;
	// const uint64_t b = f & M32;
	// const uint64_t c = pow10_f >> 32;
	// const uint64_t d = pow10_f & M32;
	// const uint64_t ac = a * c;
	// const uint64_t bc = b * c;
	// const uint64_t ad = a * d;
	// const uint64_t bd = b * d;
	// uint64_t hi = ac + (ad >> 32) + (bc >> 32);
	// uint64_t lo = bd + (ad & M32) + (bc & M32);
	// uint64_t mul_res_f = hi + (lo >> 63);

	uint64_t mul_res_f;
	_mulx_u64(f, pow10_f, &mul_res_f);
	int mul_res_e = e + pow10_e + 64;
	uint64_t add_num = ((mul_res_f >> (-mul_res_e - 1)) & 1);
	int64_t num0_rest = (mul_res_f >> (-mul_res_e)) + add_num;

	int num01 = int((double)num0_rest * _10en[-Precision + 1 + 324]); // 1e-15
	int64_t num2_rest = num0_rest - num01 * int64_t(_10en[Precision - 1 + 324]);
	if (num2_rest < 0)
	{
		// num01--;
		// num2_rest += int64_t(_10en[Precision - 1 + 324]);
	}
	num01 -= (num2_rest < 0);
	num2_rest += (num2_rest < 0) ? int64_t(_10en[Precision - 1 + 324]) : 0; //[1e14,1e15)
	// num2_rest = (num2_rest < 0) ? (num2_rest + int64_t(_10en[Precision - 1 + 324])):num2_rest;
	// num2_rest = num0_rest - num01 * int64_t(_10en[Precision - 1 + 324]);
	int num0 = (num01 * 103) >> 10; // 等于num01/10;
	int num1 = num01 - num0 * 10;
	buffer[index + 0] = '0' + num0;
	if (Precision > 0)
	{
		buffer[index + 1] = '.';
	}
	const int frac_div_2 = Precision / 2; // Precision
	const int frac_rest = Precision % 2;  // 1 or 0
	// write 后16位
	{
		short *buffer_short_ptr = (short *)&buffer[index + 1 + (Precision > 0) + frac_rest];
		const __m512d pow10_n2_n16_d = _mm512_set_pd(1e-2, 1e-4, 1e-6, 1e-8, 1e-10, 1e-12, 1e-14, 1e-16);
		const __m512i pow10_2_16_i = _mm512_set_epi64(1e2, 1e4, 1e6, 1e8, 1e10, 1e12, 1e14, 1e16);
		const __m512d pow10_n0_n14_d = _mm512_set_pd(1e0, 1e-2, 1e-4, 1e-6, 1e-8, 1e-10, 1e-12, 1e-14);
		__m512d num2_rest_d = _mm512_set1_pd((double)num2_rest);
		__m512i num2_rest_i = _mm512_set1_epi64(num2_rest);

		//__m512d num2_rest_d_mul_pow10_n2_n16_d = _mm512_mul_pd(num2_rest_d, pow10_n2_n16_d);

		__m512i result_8 = _mm512_cvttpd_epi64(_mm512_cvtepi64_pd(num2_rest_i - _mm512_cvttpd_epi64(num2_rest_d * pow10_n2_n16_d) * pow10_2_16_i) * pow10_n0_n14_d);

		uint64_t result[8];
		_mm512_storeu_epi64(result, result_8);
		index += frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1);
		{
			int e10_abs = abs(e10);
			short *buffer_short_ptr = (short *)&buffer[index];
			*buffer_short_ptr = (e10 < 0) ? short('-' * 256 + 'e') : short('+' * 256 + 'e');
			if (e10_abs < 100) [[likely]]
			{
				short *buffer_short_ptr = (short *)&buffer[index + 2];
				*buffer_short_ptr = short_array[e10_abs];
				index += 2 + 2;
			}
			else
			{
				buffer[index + 2] = ((e10_abs * 82) >> 13) + '0'; // 百分位
				short *buffer_short_ptr = (short *)&buffer[index + 3];
				buffer_short_ptr[0] = short_array[e10_abs - ((e10_abs * 82) >> 13) * 100]; // 后两位
				index += 3 + 2;
			}
			// index += 3 + 2 - (e10_abs < 100);
		}

		int num12 = num1 * 10 + result[0];
		buffer_short_ptr[0] = short_array[num12]; // 0
		for (int i = 1; i < frac_div_2; ++i)
		{
			buffer_short_ptr[i] = short_array[result[i]]; // 1-7
		}
		if (frac_rest == 1)
		{
			// buffer[(index) + 1 + (Precision > 0)] = num123456 + '0';
		}
	}
	// write e10
	if (0)
	{
		int e10_abs = abs(e10);
		short *buffer_short_ptr = (short *)&buffer[index];
		*buffer_short_ptr = (e10 < 0) ? short('-' * 256 + 'e') : short('+' * 256 + 'e');
		if (e10_abs < 100)
		{
			short *buffer_short_ptr = (short *)&buffer[index + 2];
			*buffer_short_ptr = short_array[e10_abs];
			index += 2 + 2;
		}
		else
		{
			buffer[index + 2] = ((e10_abs * 82) >> 13) + '0'; // 百分位
			short *buffer_short_ptr = (short *)&buffer[index + 3];
			buffer_short_ptr[0] = short_array[e10_abs - ((e10_abs * 82) >> 13) * 100]; // 后两位
			index += 3 + 2;
		}
		// index += 3 + 2 - (e10_abs < 100);
	}
	buffer[index] = '\0';
	return index + 1;
}
template <int Precision = 16>
int my_dou_to_sci_pure2(double value, char *buffer)
{
	static const short short_array[100] = {12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640,
										   12337, 12593, 12849, 13105, 13361, 13617, 13873, 14129, 14385, 14641,
										   12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642,
										   12339, 12595, 12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643,
										   12340, 12596, 12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644,
										   12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645,
										   12342, 12598, 12854, 13110, 13366, 13622, 13878, 14134, 14390, 14646,
										   12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391, 14647,
										   12344, 12600, 12856, 13112, 13368, 13624, 13880, 14136, 14392, 14648,
										   12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649};
	static const char DIGIT_TABLE[200] = {
		'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',
		'1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',
		'2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
		'3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9',
		'4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9',
		'5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
		'6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',
		'7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9',
		'8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
		'9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9'};
	// int is_negative = value < 0.0;
	buffer[0] = '-';
	int index = value < 0.0;
	value = std::fabs(value);
	uint64_t value_u64 = *(uint64_t *)&value;
	int ieee754_exp11 = (value_u64 >> 52);
	uint64_t f;
	int e;
	int e2;
	if (ieee754_exp11 == 0)
	{
		// 计算前缀0的个数
#if defined(_MSC_VER) && defined(_M_AMD64)
		unsigned long clz = __lzcnt64(value_u64);
#elif defined(__GNUC__)
		int clz = __builtin_clzll(value_u64);
#endif
		f = (value_u64) << clz;
		e = -1074 - clz;
		e2 = -1022 - (clz - 11);
	}
	else
	{
		// f = ((value_u64 & ((1ull << 52) - 1)) | (1ull << 52)) << 11;
		f = (value_u64 << 11) | ((1ull) << 63);
		e = ieee754_exp11 - 1023 - 52 - 11;
		e2 = ieee754_exp11 - 1023; // =e+63
	}
	int e10_tmp = ((e2 * 78913) >> 18);
	int e10 = e10_tmp + (value >= _10en[e10_tmp + 1 + 324]) - (value_u64 == 2); // L1 cache 3cycle
	int pow10_e = (((-e10 + Precision) * 1741647) >> 19) - 63;
	uint64_t pow10_f = powers_ten[343 + (-e10) + Precision]; // L1 cache 3cycle
	e10 = (value_u64 == 0 ? 0 : e10);						 // 处理特殊值0
	uint64_t mul_res_f;
#if defined(_MSC_VER) && defined(_M_AMD64) // msvc
	_umul128(f, pow10_f, &mul_res_f);
#elif defined(__GNUC__) && defined(_M_AMD64) // gcc
	_mulx_u64(f, pow10_f, &mul_res_f);
#else
	const uint64_t M32 = 0xFFFFFFFF;
	const uint64_t a = f >> 32;
	const uint64_t b = f & M32;
	const uint64_t c = pow10_f >> 32;
	const uint64_t d = pow10_f & M32;
	const uint64_t ac = a * c;
	const uint64_t bc = b * c;
	const uint64_t ad = a * d;
	const uint64_t bd = b * d;
	uint64_t hi = ac + (ad >> 32) + (bc >> 32);
	uint64_t lo = bd + (ad & M32) + (bc & M32);
	uint64_t mul_res_f = hi; // +(lo >> 63); // 不加上lo>>63 可以提高一点点速度
#endif
	int mul_res_e = e + pow10_e + 64;
	// uint64_t add_num = ((mul_res_f >> (-mul_res_e - 1)) & 1);
	int64_t num0_rest = (mul_res_f >> (-mul_res_e)) + ((mul_res_f >> (-mul_res_e - 1)) & 1);

	// int num01 = int((double)num0_rest * _10en[-Precision + 1 + 324]); // 1e-15
	// int64_t num2_rest = num0_rest - num01 * int64_t(_10en[Precision - 1 + 324]);
	// num01 -= (num2_rest < 0);
	// num2_rest += (num2_rest < 0) ? int64_t(_10en[Precision - 1 + 324]) : 0; //[1e14,1e15)
	// int num0 = (num01 * 103) >> 10; // 等于num01/10,小数点前一位的值
	// int num1 = num01 - num0 * 10;//小数点后第一位的值
	int num01 = num0_rest / int64_t(_10en[Precision - 1 + 324]); // 编译期常量，比上述方式快
	int64_t num2_rest = num0_rest - num01 * int64_t(_10en[Precision - 1 + 324]);
	int num0 = (num01 * 103) >> 10; // 等于num01/10,小数点前一位的值
	int num1 = num01 - num0 * 10;	// 小数点后第一位的值

	buffer[index + 0] = '0' + num0;
	if (Precision > 0)
		buffer[index + 1] = '.';
	const int frac_div_2 = Precision / 2; // Precision/2
	const int frac_rest = Precision % 2;  // 1 or 0
	// write 后16位
	// if(Precision>0)
	{
		short *buffer_short_ptr = (short *)&buffer[index + 1 + (Precision > 0) + frac_rest];
		const __m512d pow10_n2_n16_d = _mm512_set_pd(1e-2, 1e-4, 1e-6, 1e-8, 1e-10, 1e-12, 1e-14, 1e-16);
		const __m512i pow10_2_16_i = _mm512_set_epi64(1e2, 1e4, 1e6, 1e8, 1e10, 1e12, 1e14, 1e16);
		const __m512d pow10_n0_n14_d = _mm512_set_pd(1e0, 1e-2, 1e-4, 1e-6, 1e-8, 1e-10, 1e-12, 1e-14);
		__m512d num2_rest_d = _mm512_set1_pd((double)num2_rest);
		__m512i num2_rest_i = _mm512_set1_epi64(num2_rest);
		__m512d num2r_mul_p10_d = _mm512_mul_pd(num2_rest_d, pow10_n2_n16_d);
		__m512i num2r_mul_p10_i = _mm512_cvttpd_epi64(num2r_mul_p10_d);
		__m512i num2r_div_p10_i = _mm512_mullo_epi64(num2r_mul_p10_i, pow10_2_16_i);
		__m512i num2r_sub_num2r_div_p10_i = _mm512_sub_epi64(num2_rest_i, num2r_div_p10_i);
		__m512d num2r_sub_num2r_div_p10_d = _mm512_cvtepi64_pd(num2r_sub_num2r_div_p10_i);
		__m512d num2r_result_d = _mm512_mul_pd(num2r_sub_num2r_div_p10_d, pow10_n0_n14_d);
		__m512i result_8 = _mm512_cvttpd_epi64(num2r_result_d);
		// 有严重的指令依赖，如何优化？
		/*__m512i result_8 = _mm512_cvttpd_epi64(_mm512_mul_pd(_mm512_cvtepi64_pd(_mm512_sub_epi64(num2_rest_i, _mm512_mullo_epi64(
			_mm512_cvttpd_epi64( _mm512_mul_pd(num2_rest_d, pow10_n2_n16_d) ), pow10_2_16_i))
		), pow10_n0_n14_d));*/
		uint64_t result[8];
		_mm512_storeu_epi64(result, result_8);
		index += frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1);
		// write e10
		{
			int e10_abs = abs(e10);
			short *buffer_short_ptr = (short *)&buffer[index];
			*buffer_short_ptr = (e10 < 0) ? short('-' * 256 + 'e') : short('+' * 256 + 'e');
			if (e10_abs < 100)
			{
				short *buffer_short_ptr = (short *)&buffer[index + 2];
				*buffer_short_ptr = short_array[e10_abs];
				index += 2 + 2;
			}
			else
			{
				buffer[index + 2] = ((e10_abs * 82) >> 13) + '0'; // 百分位,等于e10_abs/100
				short *buffer_short_ptr = (short *)&buffer[index + 3];
				buffer_short_ptr[0] = short_array[e10_abs - ((e10_abs * 82) >> 13) * 100]; // 后两位
				index += 3 + 2;
			}
		}

		int num12 = num1 * 10 + result[0];
		buffer_short_ptr[0] = short_array[num12]; // 0
		for (int i = 1; i < frac_div_2; ++i)
		{
			buffer_short_ptr[i] = short_array[result[i]]; // 1-7
		}
		if (frac_rest == 1)
		{
			// buffer[(index) + 1 + (Precision > 0)] = num123456 + '0';
		}
	}
	// write e10
	if (0)
	{
		int e10_abs = abs(e10);
		short *buffer_short_ptr = (short *)&buffer[index];
		*buffer_short_ptr = (e10 < 0) ? short('-' * 256 + 'e') : short('+' * 256 + 'e');
		if (e10_abs < 100)
		{
			short *buffer_short_ptr = (short *)&buffer[index + 2];
			*buffer_short_ptr = short_array[e10_abs];
			index += 2 + 2;
		}
		else
		{
			buffer[index + 2] = ((e10_abs * 82) >> 13) + '0'; // 百分位
			short *buffer_short_ptr = (short *)&buffer[index + 3];
			buffer_short_ptr[0] = short_array[e10_abs - ((e10_abs * 82) >> 13) * 100]; // 后两位
			index += 3 + 2;
		}
	}
	buffer[index++] = '\0';
	return index;
}
template <int Precision = 16>
int my_dou_to_sci_pure3(double value, char *buffer)
{
	static const short short_array[100] = {12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640,
										   12337, 12593, 12849, 13105, 13361, 13617, 13873, 14129, 14385, 14641,
										   12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642,
										   12339, 12595, 12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643,
										   12340, 12596, 12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644,
										   12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645,
										   12342, 12598, 12854, 13110, 13366, 13622, 13878, 14134, 14390, 14646,
										   12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391, 14647,
										   12344, 12600, 12856, 13112, 13368, 13624, 13880, 14136, 14392, 14648,
										   12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649};
	buffer[0] = '-';
	int index = value < 0.0;
	value = std::fabs(value);
	uint64_t value_u64 = *(uint64_t *)&value;
	int ieee754_exp11 = (value_u64 >> 52);
	int value_eq_2 = (value_u64 == 2);
	uint64_t f;
	// int e;
	int e2;
	if (ieee754_exp11 == 0)
	{
		// 计算前缀0的个数
#if defined(_MSC_VER) && defined(_M_AMD64)
		unsigned long clz = __lzcnt64(value_u64);
#elif defined(__GNUC__)
		int clz = __builtin_clzll(value_u64);
#endif
		f = (value_u64) << clz;
		// e = -1074 - clz;
		e2 = -1022 - (clz - 11);
	}
	else
	{
		// f = ((value_u64 & ((1ull << 52) - 1)) | (1ull << 52)) << 11;
		f = (value_u64 << 11) | ((1ull) << 63);
		// e = ieee754_exp11 - 1023 - 52 - 11;
		e2 = ieee754_exp11 - 1023; // = e+63
	}
	int e10_tmp = ((e2 * 78913) >> 18);
	int e10 = e10_tmp + (value >= _10en[e10_tmp + 1 + 324]) - value_eq_2; // - (value_u64 == 2);//L1 cache 3cycle
	// if(value_u64 == 2)e10--;
	// int pow10_e = (((-e10 + Precision) * 1741647) >> 19) - 63;
	uint64_t pow10_f = powers_ten[343 + (-e10) + Precision]; // L1 cache 3cycle
	int mul_res_e = e2 - 63 + (((-e10 + Precision) * 1741647) >> 19) - 63 + 64;
	e10 = (value_u64 == 0 ? 0 : e10); // 处理特殊值0
	uint64_t mul_res_f;
#if defined(_MSC_VER) && defined(_M_AMD64) // msvc
	_umul128(f, pow10_f, &mul_res_f);
#elif defined(__GNUC__) && defined(_M_AMD64) // gcc
	_mulx_u64(f, pow10_f, &mul_res_f);
#else
	const uint64_t M32 = 0xFFFFFFFF;
	const uint64_t a = f >> 32;
	const uint64_t b = f & M32;
	const uint64_t c = pow10_f >> 32;
	const uint64_t d = pow10_f & M32;
	const uint64_t ac = a * c;
	const uint64_t bc = b * c;
	const uint64_t ad = a * d;
	const uint64_t bd = b * d;
	uint64_t hi = ac + (ad >> 32) + (bc >> 32);
	uint64_t lo = bd + (ad & M32) + (bc & M32);
	uint64_t mul_res_f = hi; // +(lo >> 63); // 不加上lo>>63 可以提高一点点速度
#endif
	// int mul_res_e = e + pow10_e + 64;//
	// int mul_res_e = ieee754_exp11 - 1023 - 52 - 11 + (((-e10 + Precision) * 1741647) >> 19) - 63 + 64;

	int64_t num0_rest = (mul_res_f >> (-mul_res_e)) + ((mul_res_f >> (-mul_res_e - 1)) & 1);
	int num01 = num0_rest / int64_t(_10en[Precision - 1 + 324]); // 编译期常量，比上述方式快
	int64_t num2_rest = num0_rest - num01 * int64_t(_10en[Precision - 1 + 324]);
	int num0 = (num01 * 103) >> 10; // 等于num01/10,小数点前一位的值
	int num1 = num01 - num0 * 10;	// 小数点后第一位的值
	//int num0 = num01 / 10; // 等于num01/10,小数点前一位的值
	//int num1 = num01 % 10;	// 小数点后第一位的值

	buffer[index + 0] = '0' + num0;
	if (Precision > 0)
		buffer[index + 1] = '.';
	const int frac_div_2 = Precision / 2; // Precision/2
	const int frac_rest = Precision % 2;  // 1 or 0
	{
		short *buffer_short_ptr = (short *)&buffer[index + 1 + (Precision > 0) + frac_rest];
		const __m512d pow10_n2_n16_d = _mm512_set_pd(1e-2, 1e-4, 1e-6, 1e-8, 1e-10, 1e-12, 1e-14, 1e-16);
		const __m512i pow10_2_16_i = _mm512_set_epi64(1e2, 1e4, 1e6, 1e8, 1e10, 1e12, 1e14, 1e16);
		const __m512d pow10_n0_n14_d = _mm512_set_pd(1e0, 1e-2, 1e-4, 1e-6, 1e-8, 1e-10, 1e-12, 1e-14);
		__m512d num2_rest_d = _mm512_set1_pd((double)num2_rest);
		__m512i num2_rest_i = _mm512_set1_epi64(num2_rest);
		__m512d num2r_mul_p10_d = _mm512_mul_pd(num2_rest_d, pow10_n2_n16_d);
		__m512i num2r_mul_p10_i = _mm512_cvttpd_epi64(num2r_mul_p10_d);
		__m512i num2r_div_p10_i = _mm512_mullo_epi64(num2r_mul_p10_i, pow10_2_16_i);
		__m512i num2r_sub_num2r_div_p10_i = _mm512_sub_epi64(num2_rest_i, num2r_div_p10_i);
		__m512d num2r_sub_num2r_div_p10_d = _mm512_cvtepi64_pd(num2r_sub_num2r_div_p10_i);
		__m512d num2r_result_d = _mm512_mul_pd(num2r_sub_num2r_div_p10_d, pow10_n0_n14_d);
		__m512i result_8 = _mm512_cvttpd_epi64(num2r_result_d);


		// int64_t num12345678 = num2_rest;
		// int num1234 = num12345678/int(1e8);
		// int num5678 = num12345678%int(1e8);
		// int num12_=num1234/int(1e4);
		// int num34=num1234%int(1e4);
		// int num56=num5678/int(1e4);
		// int num78=num5678%int(1e4);
		// int num1=num12_/100;
		// int num2=num12_%100;
		// int num3=num34/100;
		// int num4=num34%100;
		// int num5=num56/100;
		// int num6=num56%100;
		// int num7=num78/100;
		// int num8=num78%100;

		// 有严重的指令依赖，如何优化？
		/*__m512i result_8 = _mm512_cvttpd_epi64(_mm512_mul_pd(_mm512_cvtepi64_pd(_mm512_sub_epi64(num2_rest_i, _mm512_mullo_epi64(
			_mm512_cvttpd_epi64( _mm512_mul_pd(num2_rest_d, pow10_n2_n16_d) ), pow10_2_16_i))
		), pow10_n0_n14_d));*/
		uint64_t result[8];

		// result[0]=num1;
		// result[1]=num2;
		// result[2]=num3;
		// result[3]=num4;
		// result[4]=num5;
		// result[5]=num6;
		// result[6]=num7;
		// result[7]=num8;


		_mm512_storeu_epi64(result, result_8);
		index += frac_div_2 * 2 + 1 + (Precision > 0) + (frac_rest == 1);
		// write e10
		{
			int e10_abs = abs(e10);
			// short* buffer_short_ptr = (short*)&buffer[index];
			*(short *)&buffer[index] = (e10 < 0) ? short('-' * 256 + 'e') : short('+' * 256 + 'e');
			if (e10_abs < 100)
			{
				// short* buffer_short_ptr = (short*)&buffer[index + 2];
				*(short *)&buffer[index + 2] = short_array[e10_abs];
				index += 2 + 2;
			}
			else
			{
				buffer[index + 2] = ((e10_abs * 82) >> 13) + '0'; // 百分位,等于e10_abs/100
				// short* buffer_short_ptr = (short*)&buffer[index + 3];
				*(short *)&buffer[index + 3] = short_array[e10_abs - ((e10_abs * 82) >> 13) * 100]; // 后两位
				index += 3 + 2;
			}
		}
		int num12 = num1 * 10 + result[0];
		buffer_short_ptr[0] = short_array[num12]; // 0
		for (int i = 1; i < frac_div_2; ++i)
		{
			buffer_short_ptr[i] = short_array[result[i]]; // 1-7
		}
		if (frac_rest == 1)
		{
			// buffer[(index) + 1 + (Precision > 0)] = num123456 + '0';
		}
	}
	buffer[index++] = '\0';
	return index;
}
template <int t = 0, int Precision = 6>
int myDoubleToScientific(double value, char *buffer, int precision = 6)
{
	int index = 0;
	// 0-99的ascii码
	static const short short_array[100] = {12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640,
										   12337, 12593, 12849, 13105, 13361, 13617, 13873, 14129, 14385, 14641,
										   12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642,
										   12339, 12595, 12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643,
										   12340, 12596, 12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644,
										   12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645,
										   12342, 12598, 12854, 13110, 13366, 13622, 13878, 14134, 14390, 14646,
										   12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391, 14647,
										   12344, 12600, 12856, 13112, 13368, 13624, 13880, 14136, 14392, 14648,
										   12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649};
	// 处理特殊情况：无穷大、NaN、0
	if (value == 0.0)
	{
		if (Precision == 0)
		{
			strcpy(buffer, "0e+00");
			return 5;
		}
		if (Precision == 1)
		{
			strcpy(buffer, "0.0e+00");
			return 7;
		}
		if (Precision == 2)
		{
			strcpy(buffer, "0.00e+00");
			return 8;
		}
		if (Precision == 3)
		{
			strcpy(buffer, "0.000e+00");
			return 9;
		}
		if (Precision == 4)
		{
			strcpy(buffer, "0.0000e+00");
			return 10;
		}
		if (Precision == 5)
		{
			strcpy(buffer, "0.00000e+00");
			return 11;
		}
		if (Precision == 6)
		{
			strcpy(buffer, "0.000000e+00");
			return 12;
		}
		if (Precision == 7)
		{
			strcpy(buffer, "0.0000000e+00");
			return 13;
		}
		if (Precision == 8)
		{
			strcpy(buffer, "0.00000000e+00");
			return 14;
		}
		if (Precision == 9)
		{
			strcpy(buffer, "0.000000000e+00");
			return 15;
		}
		// strcpy(buffer, "0.000000e+00");
		// return 12;
	}

	// int jiema = ((*(reinterpret_cast<int64_t *>(&value)) >> 52) & 0x7FF) - 1023;

	// //jiema==1024

	// if (jiema == 1024)
	// {
	// 	// std::string s1 = std::format("{:.6e}",value);
	// 	// printf("1024  %s\n",s1.c_str());
	// 	//  阶码全1,尾数不全0
	// 	if (std::isnan(value))
	// 	{
	// 		// printf("nan\n");
	// 		// strcpy(buffer, "nan");
	// 		// return 3;
	// 	}
	// 	// 阶码全1,尾数全0
	// 	if (std::isinf(value))
	// 	{
	// 		// printf("inf\n");
	// 		// strcpy(buffer, "inf");
	// 		// return 3;
	// 	}
	// 	strcpy(buffer, "nan");
	// 	return 3;
	// }
	// else if (jiema == -1023)
	// {
	// 	// printf("-1023\n");
	// 	strcpy(buffer, "0.000000e+00");
	// 	return 12;
	// }

	// if ((jiema == 1024) || (jiema == -1023))
	{
		// return sprintf(buffer, "%.6le", value);
	}

	// long long int weishu = ((*(reinterpret_cast<uint64_t *>(&value))) & (1ll<<53-1) );
	// if (weishu == 0)
	// 	weishu = 1ll << 52;

	// if(jiema==1024||jiema==-1023){

	// }

	int is_negative = 0;
	// double value_back=value;
	int exponent; //= static_cast<int>(static_cast<int>(((*(reinterpret_cast<uint64_t *>(&value)) >> 52) & 0x7FF) - 1023) * (1.0 / (681. / 205.)));
	//-1023 -> -307
	// 1024 -> 308

	// value的正负不影响exponent结果

	// int sign = (value > 0) - (value < 0);//not use branch,get the sign of number
	// int sign = (number >> (sizeof(int) * CHAR_BIT - 1)) & 1; //floatz
	// sign == 1 positive
	// sign == 0 negative;
	// is_negative = (value > 0) - (value < 0);
	// is_negative=( *(reinterpret_cast<int64_t *>(&value)) >> (52) ) & 1;

	// int sign = ((*(reinterpret_cast<uint64_t *>(&value)) >> 63) & 0x1);
	//  sign=0 +
	//  sign=1 -
	// if (sign)
	buffer[0] = (value < 0) * '-';
	// buffer[0] = '-';
	is_negative = (value < 0);
	// is_negative=1;
	if (value < 0) // 1 branch
	{
		// buffer[0] = '-';
		// value = -value;
		// is_negative = 1;
	}
	else
	{
		// buffer[0] = '+';//正数时可以不用输出'+';
		//  is_negative = 0;
	}

	// value = fabs(value);//编译器自动优化

	double num;

#if 0
	if (exponent >= 0)
		num = value * fastPowDouble(0.1, exponent); // 后续是否可以优化这个函数,exponent大时比较耗时
	else
		num = value * fastPowDouble(10.0, -exponent);
#else
	// num = value * _10en[(-exponent) + 308]; // 提前计算，采用查表方式
#endif

	if (num >= 10.0) // 3
	{
		// num *= 1e-1;
		//++exponent;
	}
	if (num < 1.0) // 4
	{
		// num *= 1e1;
		//--exponent;
	}
	// num = value * _10en[(-exponent) + 308];//[]
	exponent = getb(value); //-254
	if (t == 1)
		printf("exponent=%d\n", exponent);
	// num = value * _10en[( -exponent) + 308];//[1,10)
	// now num:[1,10)

	// int numa = num >= 10.0;
	// int numb = num < 1.0 ;
	// num *= (9.0*numb+1.0-0.9*numa);
	// exponent += (numa-numb);

	// long long int num_store = static_cast<long long int>(num); // 获取小数点前的那一位
	// int64_t num0 = labs(int64_t(num));
	double value_mul = _10en[(-exponent) + Precision + 308];
	double tmp_num;
	if (exponent <= (-308 + (Precision - 1))) [[unlikely]] // 1% 概率,随机数的情况下
	{													   //-303      branch 2
		tmp_num = value * _10en[-(exponent - (-308 + Precision)) + 308] * 1e308;
	}
	else
	{
		tmp_num = value * value_mul;
	}

	int num0123456 = labs(double_to_int64(tmp_num));
	int num0 = int(num0123456 * _10en[-Precision + 308]);
	int num123456 = num0123456 - int(num0123456 * _10en[-Precision + 308]) * int(_10en[Precision + 308]);
	// if(num0123456 == 10000000)
	if (num0123456 == int(_10en[Precision + 1 + 308]))
	{
		exponent += 1;
		num0 = 1;
		// num123456=0;
	}
	else
	{
		// num0 = int(num0123456 * 1e-6);
		// num123456 = num0123456 - int(num0123456 * 1e-6) * 1000000; //
	}
	// num -= num_store;//
	if (t == 1)
	{
		printf("num=%.20le num0=%lld ", num, num0);
	}

	double num_e6_double = num * 1e6;
	if (t == 1)
	{
		printf("num_e6_double=%.20le  ", num_e6_double);
	}
	// long long int num_e6_int = ((long long int)(num_e6_double));
	if (t == 1)
	{
		printf("num0123456=%lld num123456=%lld \n", num0123456, num123456);
	}
	// int num_e6_int =(int(num*1e7) /10) % 1000000;

#if 1
	// int num_e7_int = int(num * 1e7);//默认保留后6位小数，需要知道7位的值,以四舍五入。
	// if ((num_e7_int - num_e6_int*10) >= 5)//50%
	// { // 四舍五入
	// 	num_e6_int++;
	// }
	// 上述if代码会有50%概率分支失效。故采用下列写法，减少分支预测失败开销
	// num_e6_int += ((int(num * 1e7) - num_e6_int * 10) >= (5)); // 不进行分支
	// 会有999999的情况

	// int precision = 6;
#if 1
	// if (((weishu % (1ll << (52 - (precision - exponent + 1 + jiema)))) == 0))
	// {
	// 	if (abs(jiema) <= 52)
	// 		if (((weishu / (1ll << (52 - (precision - exponent + 1 + jiema)))) % 2 == 1))
	// 			if (num_e6_int % 2 == 1) // jishu
	// 				{
	// 					//num_e6_int++;
	// 					if(t==1){
	// 						//printf("1:num_e6_int++;  ");
	// 					}
	// 				}		 // 对齐到偶数
	// }
#endif
	// if (((int(num * 1e10) - num_e6_int * 10000) >= (5000)))
	// if (  (num_e6_double ) > (num_e6_int + 0.5) )
	// //if (  (num_e6_double ) > (int(num_e6_double) + 0.5) )
	// //if( int((num+5e-7)*1e6) > int((num)*1e6) )
	// {
	// 	//num_e6_int += 1;
	// 	if(t==1){
	// 		//printf("2:num_e6_int++;\n");
	// 	}
#if 1
	// if (((weishu % (1ll << (52 - (precision - exponent + 1 + jiema)))) == 0))
	// {
	// 	if (abs(jiema) <= 52)
	// 		if (((weishu / (1ll << (52 - (precision - exponent + 1 + jiema)))) % 4 == 1))
	// 		{
	// 			{
	// 				//num_e6_int--;
	// 				if(t==1){
	// 					//printf("3:num_e6_int--;  ");
	// 				}
	// 			}
	// 		}
	// }

#endif
	//}
	// if(t==1)printf("\n");
#endif
	short num12_ = 0;
	short num34_ = 0;
	short num56_ = 0;

	// if (num_e6_int == 1000000)
	// {
	// 	num_store++;
	// 	if (num_store == 10)
	// 	{
	// 		num_store = 1;
	// 		exponent++;
	// 	}
	// 	num12_ = num34_ = num56_ = 12336; //"00"
	// }
	// else
	//{
	double num123456_double = num123456;
	const int frac_div_2 = Precision / 2; // Precision
	const int frac_rest = Precision % 2;  // 1 or 0
	char num_frac[frac_div_2];
	short ascii_num_frac[frac_div_2];
	char num_rest;
	for (int i = 0; i < frac_div_2; i++)
	{
		num_frac[i] = num123456 * _10en[-(Precision - 2 * i - 2) + 308];
		ascii_num_frac[i] = short_array[num_frac[i]];
		num123456 -= num_frac[i] * _10en[(Precision - 2 * i - 2) + 308];
	}
	// num12_ = short_array[num_frac[0]];
	// num34_ = short_array[num_frac[1]];
	// num56_ = short_array[num_frac[2]];
	num12_ = ascii_num_frac[0];
	num34_ = ascii_num_frac[1];
	num56_ = ascii_num_frac[2];

	// if(frac_rest != 0){

	// }

	// int num12 = num_e6_int / 10000;
	// int num12 = num123456_double * 0.0001;
	// // int num12=num123456/10000;
	// // num12_=num12;

	// num12_ = short_array[num12]; // 访问一级cache
	// // num12_ = num12*0.1 + num12-int(num12*0.1)*10;

	// int num56 = num123456 - int(num123456_double * 0.01) * 100;
	// // int num56=num123456%100;
	// // num56_=num56;
	// num56_ = short_array[num56]; // 访问一级cache
	// // num56_ = num56*0.1 + num56-int(num56*0.1)*10;

	// // int num34 = (num_e6_int / 100) % 100;
	// int num34 = int(num123456_double * 0.01) - num12 * 100;
	// // int num34=(num123456/100)%100;
	// // num34_=num34;
	// num34_ = short_array[num34]; // 访问一级cache
	// 							 // num34_ = num34*0.1 + num34-int(num34*0.1)*10;

	// int num56 = num_e6_int % 100; //
	//  int ans=0;
	//  for(int i=0;i<6;++i){
	//  	int tmp = num123456 - int(num123456_double * 0.1) * 10;
	//  	num123456_double = num123456_double * 0.1;
	//  	ans+=tmp;
	//  }
	// num12_=num34_=num56_=ans;

	//}
#if 0
	//实时计算好像会慢些
	short num12_ = ((num12 / 10 + int('0')) + (((num12 - (num12 / 10) * 10) + int('0')) * (1 << 8)));
	short num34_ = ((num34 / 10 + int('0')) + (((num34 - (num34 / 10) * 10) + int('0')) * (1 << 8)));
	short num56_ = ((num56 / 10 + int('0')) + (((num56 - (num56 / 10) * 10) + int('0')) * (1 << 8)));
#else

#endif
	union
	{ // 8个byte的结构体
		struct
		{
			short i;
			short j;
			short k;
			short l;
		} n;
		int64_t ll;
	} v;
	// v.n.i = short('.') * short((1 << 8)) + short('0') + short(num0);
	v.n.i = '.' * (1 << 8) + '0' + num0;
	v.n.j = num12_; // 小数点后12位
	v.n.k = num34_; // 小数点后34位
	v.n.l = num56_; // 小数点后56位

	*((int64_t *)(&(buffer[is_negative]))) = v.ll;

	// int _43_45 =  ((exponent >> 31) & 1) * 2  + 43;//不采用分支 计算 正负符号

	// if(0)
	int exponent_abs = abs(exponent);
	int exponent_tag = 2 * (exponent < 0) + int('+'); // '-' or '+

	if (exponent_abs < 100)
	{ // 0-99
		*((int64_t *)(&(buffer[is_negative + 8]))) = int('e') +
													 exponent_tag * (1 << 8) +
													 short_array[exponent] * (1 << 16);
	}
	else
	{ // >=100
		*((int64_t *)(&(buffer[is_negative + 8]))) = (int64_t)(int('e') +
															   exponent_tag * (1 << 8) +
															   int((exponent / 100 + int('0'))) * (1 << 16) +
															   // short_array[exponent%100] * (1ll << 24));
															   int(((exponent / 10) % 10 + int('0'))) * (1 << 24) +
															   (int64_t)((exponent % 10 + int('0'))) * (1ll << 32));
	}

	if (0)
		if (exponent < 0)
		{
			exponent = -exponent;
			if (exponent < 10) // 0-9
			{
				*((int64_t *)(&(buffer[is_negative + 8]))) = int('e') +
															 int('-') * (1 << 8) +
															 int('0') * (1 << 16) +
															 (exponent + int('0')) * (1 << 24);
			}
			else if (exponent < 100) // 10-99
			{
				*((int64_t *)(&(buffer[is_negative + 8]))) = int('e') +
															 int('-') * (1 << 8) +
															 short_array[exponent] * (1 << 16);
			}
			else
			{ // 100 - 307
				*((int64_t *)(&(buffer[is_negative + 8]))) = (int64_t)(int('e') +
																	   int('-') * (1 << 8) +
																	   int((exponent / 100 + int('0'))) * (1 << 16) +
																	   // short_array[exponent%100] * (1ll << 24));
																	   int(((exponent / 10) % 10 + int('0'))) * (1 << 24) +
																	   (int64_t)((exponent % 10 + int('0'))) * (1ll << 32));
			}
		}
		else
		{

			if (exponent < 10) // 0-9
			{

				*((int64_t *)(&(buffer[is_negative + 8]))) = int('e') +
															 int('+') * (1 << 8) +
															 int('0') * (1 << 16) +
															 (exponent + int('0')) * (1 << 24);
			}
			else if (exponent < 100) // 10-99
			{
				*((int64_t *)(&(buffer[is_negative + 8]))) = int('e') +
															 int('+') * (1 << 8) +
															 short_array[exponent] * (1 << 16);
			}
			else // 100 - 307
			{
				*((int64_t *)(&(buffer[8 + is_negative]))) = (int64_t)(int('e') +
																	   int('+') * (1 << 8) +
																	   int((exponent / 100 + int('0'))) * (1 << 16) +
																	   // short_array[exponent%100] * (1ll << 24));
																	   int(((exponent / 10) % 10 + int('0'))) * (1 << 24) +
																	   (int64_t)((exponent % 10 + int('0'))) * (1ll << 32));
			}
		}
	return 12 + is_negative + (exponent_abs >= 100);
}
void MyPrintF(char *char_array, const char *format, ...)
{
	va_list args;
	va_start(args, format);
	vsnprintf(char_array, 32, format, args);
	va_end(args);
}
int findLastSetBit(long long int num)
{

	if (num == 0)
	{

		return -1; // 如果num是0，没有1存在，可以返回-1或其它你喜欢的表示方法
	}

	// Brian Kernighan算法

	int position = 0;

	num &= -num; // 把num变成只包含最右边的1及其右边的所有位都为0的形式

	while (num != 0)
	{

		num >>= 1; // 右移一位

		position++;
	}

	// 由于我们是从包含最右边的1开始计数的，所以需要减去最后移位的次数以获得正确位置

	// 注意：这里的position已经计算了从'1'位到最高位的位数，所以不需要额外减1操作

	return position;
}

void test_func()
{
	auto t1 = std::chrono::high_resolution_clock::now();
	union
	{
		// little endian
		struct
		{
			unsigned char c8;
			unsigned char c7;
			unsigned char c6;
			unsigned char c5;
			unsigned char c4;
			unsigned char c3;
			unsigned char c2;
			unsigned char c1;
		} u8;
		struct
		{
			unsigned short d;
			unsigned short c;
			unsigned short b;
			unsigned short a;
		} u16;
		struct
		{
			unsigned int b;
			unsigned int a;
		} u32;
		struct
		{
			double a;
		} f64;
	} v;
	v.f64.a = 0;
	for (int i = -1022; i < 1023; ++i)
	{
		for (int j = 0; j < (1 << 20); ++j)
		{
		}
	}

	double num = 0.0;
	//[-1022,1023]
	int start = -20;
	int end = 200;

	if (start < -1022)
	{
		start = -1022;
	}
	if (end > 1023)
		end = 1023;
	// exp <=1011 no problem
	int all_error = 0;
#pragma omp parallel for
	for (int exp = 1023 + start; exp <= 1023 + end; exp++) // 1 -> 2046
	{
		int is_ok = 1;
		// v.u32.a = (exp<<20) + frac;
		// printf("exp=%d,frac=%d,num=%.10e     ",exp,frac,v.f64.a);
		// frac=1;
		// v.u32.a = (exp<<20) + frac;
		// printf("exp=%d,frac=%d,num=%.10e\n",exp,frac,v.f64.a);
		const int weishu = 20 + 3; // 20-52

		for (int frac = 0; frac <= ((1 << weishu) - 1); frac++)
		{
			// num = 0.0;
			// num = std::ldexp(static_cast<double>(frac), exp);
			// std::bitset<64> bits(*reinterpret_cast<unsigned long long*>(&num));
			// std::cout << bits << std::endl;
			// printf("num=%e\n",num);
			// if(frac == 0&&)

			v.u32.a = (exp << 20) + (frac >> (weishu - 20));
			v.u32.b = (frac % (1 << (weishu - 20))) << (32 - (weishu - 20));
			// if(frac == 1<<19 )printf("exp=%d,frac=%d,num=%.10e     ",exp,frac,v.f64.a);
			if (frac < 4)
			{
				// printf("exp=%d ,frac=%d ,num= %le\n", exp-1023, frac, v.f64.a);
			}
			if (v.f64.a < 0.0)
			{
				printf("v.f64.a < 0 error\n");
				abort();
			}
			double num = v.f64.a;
			char char_array1[32];
			char char_array2[32];
			myDoubleToScientific(num, char_array1);

			std::string str2 = std::format("{:.6e}", num);
			std::string str3 = std::string(char_array1);

			if (str2 != str3)
			{
				is_ok = 0;
				all_error++;
				sprintf(char_array2, "%.16le", num);
				std::string str1;
				str1 = std::format("{:.10e}", num);
				printf("int(log10)=%d , jiema=%d, frac=%d, weishu=%d   %s     %s  %s  %s\n", getb(num), exp - 1023, frac, findLastSetBit(frac) + 32, str1.c_str(), str2.c_str(), char_array2, str3.c_str());
			}
		}
		// printf("exp=%d,frac=%d,num=%.10e\n",exp,frac,v.f64.a);
		if (is_ok)
		{
			printf("exp=%d ok\n", exp - 1023);
		}
		else
		{
			// all_ok = 0;
			printf("exp=%d not ok--------------\n", exp - 1023);
		}
	}
	printf("all_error=%d\n", all_error);

	// v.u32.a = 1023<<20+0;
	// printf("num=%e\n",v.f64.a);
	auto t2 = std::chrono::high_resolution_clock::now();

	auto duration1 = std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count();
	printf("test_func duration1= %lf s\n", duration1 / 1e9);
}

void test_func2()
{
	std::cout << "start test_func2" << std::endl;
	std::default_random_engine e;
	e.seed(time(0));
	std::random_device rd;
	std::mt19937_64 gen(rd()); // 使用Mersenne Twister算法，并用随机数设备初始化
	// 创建一个在int64_t范围内的均匀分布
	// std::uniform_int_distribution<int64_t> dis(std::numeric_limits<int64_t>::min(), std::numeric_limits<int64_t>::max());
	auto t1 = std::chrono::high_resolution_clock::now();
	union
	{
		// little endian
		struct
		{
			unsigned char c8;
			unsigned char c7;
			unsigned char c6;
			unsigned char c5;
			unsigned char c4;
			unsigned char c3;
			unsigned char c2;
			unsigned char c1;
		} u8;
		struct
		{
			unsigned short d;
			unsigned short c;
			unsigned short b;
			unsigned short a;
		} u16;
		struct
		{
			unsigned int b;
			unsigned int a;
		} u32;
		struct
		{
			double a;
		} f64;
		struct
		{
			int64_t a;
		} i64;
	} v;
	v.f64.a = 0;
	// for (int i = -1022; i < 1023; ++i)
	// {
	// 	for (int j = 0; j < (1 << 20); ++j)
	// 	{
	// 	}
	// }

	double num = 0.0;
	//[-1022,1023]
	int start = 0;
	int end = 0;

	if (start < -1022)
	{
		start = -1022;
	}
	if (end > 1023)
		end = 1023;
	const int weishu = 20; // 20-52
	int minb = 308;
	int maxb = -308;
	int numb[308 * 2 + 1] = {0};
	double min_num = 1e-1;
	double max_num = 1e30;
	int64_t min_num_i64 = *(int64_t *)&min_num;
	// exp <=1011 no problem
	int all_error = 0;
	// #pragma omp parallel for
	long long int ALL = ((1ll << weishu) - 1);
	auto cycle_start = getcycle();
	for (int exp = 1023 + start; exp <= 1023 + end; exp++) // 1 -> 2046
	{
		int is_ok = 1;
		// v.u32.a = (exp<<20) + frac;
		// printf("exp=%d,frac=%d,num=%.10e     ",exp,frac,v.f64.a);
		// frac=1;
		// v.u32.a = (exp<<20) + frac;
		// printf("exp=%d,frac=%d,num=%.10e\n",exp,frac,v.f64.a);

		int progressBar = 0;
		int max_diff_std = 0, max_diff_my = 0, max_diff_std_my = 0;
		int all_same = 0;
		int diff1 = 0, diff2 = 0, diff3 = 0, diff_other = 0;
		char char_array1[32] = {0};
		// #pragma omp parallel for num_threads(8) proc_bind(close) reduction(+ : all_error) reduction(min : minb) reduction(max : maxb)
		for (long long int frac = 0; frac <= ((1ll << weishu) - 1); frac++)
		{
			// if(  ((frac * 100ll / ALL) % 10) == 0)
			{
				// printf("%d0%%\n",progressBar++);
			}
			// num = 0.0;
			// num = std::ldexp(static_cast<double>(frac), exp);
			// std::bitset<64> bits(*reinterpret_cast<unsigned long long*>(&num));
			// std::cout << bits << std::endl;
			// printf("num=%e\n",num);
			// if(frac == 0&&)

			// v.u32.a = (exp << 20) + (frac >> (weishu - 20));
			// v.u32.b = (frac % (1 << (weishu-20)) ) << (32 - (weishu-20) );
			//  if(frac == 1<<19 )printf("exp=%d,frac=%d,num=%.10e     ",exp,frac,v.f64.a);
			// if(frac<4)
			{
				// printf("exp=%d ,frac=%d ,num= %le\n", exp-1023, frac, v.f64.a);
			}
			// if(v.f64.a < 0.0){printf("v.f64.a < 0 error\n");abort();}
			// v.u32.a=e();
			// v.u32.b=e();

			// v.i64.a
			auto rndnum = gen(); // 1ns
			// double one = ( 1<<0 ) ;
			// int64_t rndnum_range_1_2 = rndnum & ((1ll << 52) - 1) | *(int64_t *)&one;
			// v.i64.a = rndnum_range_1_2;
			v.i64.a = rndnum;
			double num = v.f64.a;
			// if (std::fabs(num) >= 1e0 && std::fabs(num) <= 1e100)
			int num_exp = (rndnum >> 52) & 0x7ff;
			if (!(num_exp == -1023 + 1023 || num_exp == 1024 + 1023))
			// if (!( num_exp == 1024 + 1023))
			{
			}
			else
			{
				frac--;
				continue;
			}

			// auto rndnum = gen(); // 3ns
			// v.i64.a = rndnum;
			// double num = v.f64.a;

			// num=9.30334667516567265280e-254;
			// num=9.30334667516567265280e-254;
			// int jiema = ((*(reinterpret_cast<int64_t *>(&num)) >> 52) & 0x7FF) - 1023;
			// if (jiema == 1024 || jiema == -1023)
			// {
			// 	frac--;
			// 	continue;
			// }

			int64_t num_i64 = (min_num_i64 + frac);
			// double num = *(double *)&num_i64;
			//    double num = frac;

			// char char_array3[32];
			// myDoubleToScientific(num, char_array1);
			my_dou_to_sci<0, 16>(num, char_array1);
			// std::string _sprintf6_ = std::format("{:.6e}", num);
#if 1
			std::string mysci = std::string(char_array1);
			//  std::cout<<"hello world1 "<<char_array1<<std::endl;
			//  std::string str2 = std::format("{:.6e}", num);
			// sprintf(char_array3, "%le", num);
			// char * char_ptr = char_array3;
			// my_func::my__d2exp_buffered_n(char_ptr, char_ptr + 32, num , 6);
			// std::string _sprintf6_ = std::string(char_array3);
			std::string _sprintf6_ = std::format("{:.16e}", num);
			// std::cout<<"hello world3 "<<char_array3<<std::endl;

			if (_sprintf6_ != mysci)
			{
				// printf("num = %.16le\n",num);
				// printf("mysci = %s\n",mysci.c_str());
				// printf("_sprintf6_ = %s\n", _sprintf6_.c_str());

				// is_ok = 0;
				all_error++;
				int tb = getb(num);
				minb = std::min(minb, tb);
				maxb = std::max(maxb, tb);
				numb[tb + 308]++;

				double my_num = std::stod(mysci);
				double std_num = std::stod(_sprintf6_);
				uint64_t my_num_u64 = *(uint64_t *)&my_num;
				uint64_t num_u64 = *(uint64_t *)&num; // origin_num
				uint64_t std_num_u64 = *(uint64_t *)&std_num;
				int diff_std = llabs(std_num_u64 - num_u64);
				int diff_my = llabs(my_num_u64 - num_u64);
				int diff_std_my = abs(diff_std - diff_my);
				// printf("diff = %d\n",diff);
				max_diff_std = std::max(max_diff_std, diff_std);
				max_diff_my = std::max(max_diff_my, diff_my);
				max_diff_std_my = std::max(max_diff_std_my, diff_std_my);

				// if(diff_std==3)
				if (0)
				// if(diff_std_my>100000)
				{
					printf(" my_num = %.16le\n", my_num);
					print_double(my_num);
					printf(" origin = %.16le\n", num);
					print_double(num);
					printf("std_num = %.16le\n", std_num);
					print_double(std_num);
					printf("diff_std_my = %d\n", diff_std_my);
					printf("\n");
				}
				if (diff_std_my == 0)
				{
					all_same++;
				}
				else if (diff_std_my == 1)
				{
					diff1++;
#if 0
					printf("\n");
					print_double(num);
					char sprintf16[32];
					sprintf(sprintf16, "%.20le", num);
					std::string format16 = std::format("{:.16e}", num);
					printf("int(log10)=%4d , jiema=%2d, frac=%10lld, weishu=%3d   format16:%s     sprintf6/myfunc:%s  sprintf16:%s  mysci:%s\n", getb(num), exp - 1023, frac, findLastSetBit(frac) + 32, format16.c_str(), _sprintf6_.c_str(), sprintf16, mysci.c_str());
					// myDoubleToScientific<1>(num,char_array1);
					my_dou_to_sci<1, 16>(num, char_array1);
#endif
				}
				else if (diff_std_my == 2)
				{
					diff2++;
				}
				else if (diff_std_my == 3)
				{
					diff3++;
				}
				else
				{
					diff_other++;
#if 0
					printf("\n");
					print_double(num);
					char sprintf16[32];
					sprintf(sprintf16, "%.20le", num);
					std::string format16 = std::format("{:.16e}", num);
					printf("int(log10)=%4d , jiema=%2d, frac=%10lld, weishu=%3d   format16:%s     sprintf6/myfunc:%s  sprintf16:%s  mysci:%s\n", getb(num), exp - 1023, frac, findLastSetBit(frac) + 32, format16.c_str(), _sprintf6_.c_str(), sprintf16, mysci.c_str());
					// myDoubleToScientific<1>(num,char_array1);
					my_dou_to_sci<1, 16>(num, char_array1);
#endif
					// printf("error\n");
				}
#if 1
				if (diff_std_my != 0)
				{
					printf("\n");
					print_double(num);
					char sprintf16[32];
					sprintf(sprintf16, "%.20le", num);
					std::string format16 = std::format("{:.16e}", num);
					printf("int(log10)=%4d , jiema=%2d, frac=%10lld, weishu=%3d   format16:%s     sprintf6/myfunc:%s  sprintf16:%s  mysci:%s\n", getb(num), exp - 1023, frac, findLastSetBit(frac) + 32, format16.c_str(), _sprintf6_.c_str(), sprintf16, mysci.c_str());
					// myDoubleToScientific<1>(num,char_array1);
					my_dou_to_sci<1, 16>(num, char_array1);
				}
#endif
			}
			{
				// double my_num = std::stod(mysci);
				// double std_num = std::stod(_sprintf6_);
				// uint64_t my_num_u64=*(uint64_t*)&my_num;
				// uint64_t num_u64 = *(uint64_t*)&num;
				// uint64_t std_num_u64 = *(uint64_t*)&std_num;
				// int diff=llabs(std_num_u64-num_u64);
				// //printf("diff = %d\n",diff);
				// max_diff=std::max(max_diff,diff);
				// if(diff==3){
				// 	// printf("origin = %.20le\n",num);
				// 	// print_double(num);
				// 	// printf("my_num = %.20le\n",my_num);
				// 	// print_double(my_num);
				// 	// printf("\n");
				// }
				// if(diff==0){
				// 	all_same++;
				// }else if(diff==1){
				// 	diff1++;
				// }else if(diff==2){
				// 	diff2++;
				// }else if(diff==3){
				// 	diff3++;
				// }else{
				// 	diff_other++;
				// 	//printf("error\n");
				// }
			}
#endif
		}
		auto cycle_end = getcycle();
		// printf("exp=%d,frac=%d,num=%.10e\n",exp,frac,v.f64.a);
		if (is_ok)
		{
			// printf("exp=%d ok\n", exp - 1023);
		}
		else
		{
			// all_ok = 0;
			// printf("exp=%d not ok--------------\n", exp - 1023);
		}
		auto t2 = std::chrono::high_resolution_clock::now();
		auto duration1 = std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count();
		auto cycle_duration = cycle_end - cycle_start;
		printf("test_func2 duration1= %lf ms one is %lf ns\n", duration1 / 1e6, 1.0 * duration1 / ALL);
		printf("test_func2 duration cycle= %lld cycle one is %lf cycle\n", cycle_duration, 1.0 * cycle_duration / ALL);

		printf("%s\n", char_array1);
		printf("max_diff_std_my=%d \n", max_diff_std_my);
		printf("all_same=%d same_percent=%lf\n", all_same, 1.0 * all_same / (1ll << weishu));
		printf("diff1=%d diff1_percent=%lf\n", diff1, 1.0 * diff1 / (1ll << weishu));
		printf("diff2=%d diff2_percent=%lf\n", diff2, 1.0 * diff2 / (1ll << weishu));
		printf("diff3=%d diff3_percent=%lf\n", diff3, 1.0 * diff3 / (1ll << weishu));
		printf("diff_other=%d diff_other_percent=%lf\n", diff_other, 1.0 * diff_other / (1ll << weishu));
	}

	printf("test_func2 all_error=%d, percent=%lf\n", all_error, 1.0 * all_error / (1ll << weishu));
	printf("minb=%d,maxb=%d\n", minb, maxb);
	for (int i = 0, count = 0; i < (308 * 2 + 1); ++i)
	{
		if (numb[i] != 0)
		{
			// printf("%5d : %5d ,", i - 308, numb[i]);
			//  count++;
			// if (((++count) % 6) == 0)
			// printf("\n");
		}
	}
	printf("\n");
	// v.u32.a = 1023<<20+0;
	// printf("num=%e\n",v.f64.a);
}
void test_func3()
{
	std::random_device rd;
	std::mt19937_64 gen(rd());
	const int M = (1e6);	  // 32M
	const int N3 = 8 * 4; // 32 * 32 M = 1G = 1e9
	// std::vector<double> vec(M * N3);
	const int Precision = 16;
	double double_array[N3];
	double two = 2.0;
	int64_t two_i = *(int64_t *)&two;
	int64_t two_i_minus = two_i - 1;
	int64_t two_i_plus = two_i + 1;
	double two_i_minus_d = *(double *)&two_i_minus;

	for (int i = 1; i <= N3; ++i)
	{
		// vec[i] = i + 1000;
		//  vec[i] = i +;
		int64_t value = i+1;
		// vec[i] = *(double*)&value;
		//double_array[i - 1] = *(double *)&value;
		double_array[i - 1] = value;
		// double_array[i] = two_i_minus_d;
		// double_array[i] = 3.3234e-314;
		//printf("double_array[%d]=%.16le\n", i - 1, double_array[i - 1]);
		//double_array[i-1] = i;
	}
	char *char_array[N3];
	char char_array_s[32 * N3];
	for (int i = 0; i < N3; ++i)
	{
		// printf("vec[%d]=%.16le\n", i, vec[i]);
		char_array[i] = new char[32];
	}
	// my_dou_to_sci_avx512<1, Precision, N3>(&double_array[0], char_array, char_array_s);
	// printf("double_array[0]=%.16le\n", double_array[0]);
	// printf("%s\n", char_array_s);
	for (int i = 0; i < N3; ++i)
	{
		// printf("%s\n", char_array[i]);
	}
	auto t1 = std::chrono::high_resolution_clock::now();
	auto cycle1 = getcycle();
	for (int i = 0; i < M; ++i)
	{
		for (int j = 0; j < N3; ++j)
		{
			// double_array[j] = i;
		}
		my_dou_to_sci_avx512_pure<0, Precision, N3>(&double_array[0], char_array, char_array_s);
	}
	auto cycle2 = getcycle();
	auto t2 = std::chrono::high_resolution_clock::now();
	auto duration1 = std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count();
	// my_dou_to_sci_avx512<0,6,32>(double_array,char_array);
	printf("%s\n", char_array_s);
	printf("process %d double num\n", M * N3);
	printf("all cycle = %lld every cycle=%lf\n", cycle2 - cycle1, double(cycle2 - cycle1) / M / N3);
	printf("this func duration1= %lf ms one is %lf ns\n", duration1 / 1e6, 1.0 * duration1 / M / N3);
}
void test_func4()
{
	for (int i = -308; i <= 308; ++i)
	{
		double num = _10en[i + 308];
		int64_t num_i = *(int64_t *)&num;
		int64_t num_i_plus1 = num_i + 1;
		int64_t num_i_sub1 = num_i - 1;
		double num_i_plus1_d = *(double *)&num_i_plus1;
		double num_i_sub1_d = *(double *)&num_i_sub1;
		int exp = getb(num);
		int exp_plus1 = getb(num_i_plus1_d);
		int exp_sub1 = getb(num_i_sub1_d);
		if (exp != i)
			printf("error i=%d\n", i);
		if (exp_plus1 != i)
			printf("error exp_plus1 i=%d\n", i);
		if (exp_sub1 != i - 1)
			printf("error exp_sub1 i=%d\n", i);
	}
	double num_add = 1ll << 32;
	int num = 12345678;
	double num1 = 1.2345678 * (1ll << 28);
	double num_d = num;
	num_d += num_add;
	print_double(num_d);
	print_double(num1);
	// printf("num1=%lf\n", num1);
	double num_a = 1e-30;
	double num_b = 1e30;
	int64_t num_a_b = *(int64_t *)&num_b - *(int64_t *)&num_a;
	// printf("num_a_b=%lld\n", num_a_b);
	// printf("num_a exp=%d\n", getexponent(num_a));
	// printf("num_b exp=%d\n", getexponent(num_b));

	std::random_device rd;
	std::mt19937_64 gen(rd()); // 使用Mersenne Twister算法，并用随机数设备初始化

	for (int i = 0; i < 64; ++i)
	{
		int64_t num_i = gen();
		double num = *(double *)&num_i;
		printf("num=%.16le b=%d\n", num, getb(num));
	}
}
void test_func_exp0()
{

	// double a = std::atof("1.7976931348623157e308");
	//  print_double(a);
	//  printf("a = %.16le\n",a);
	std::random_device rd;
	std::mt19937_64 gen(rd()); // 使用Mersenne Twister算法，并用随机数设备初始化

	char buffer[1024];
	double num = 2.4545645e-310;
	auto i64 = ((1ull << 52) - 1);
	i64 = 0;
	const int M = 1e7;
	const int N3 = 1;
	// printf("start func_exp0\n");
	auto t1 = std::chrono::high_resolution_clock::now();
	auto cycle1 = getcycle();
	for (int i = 1; i <= M; ++i)
	{
		uint64_t i64 = i;
		// i64 &= ((1ull<<52)-1);
		double num = i64;
		// double num = *(double*)&i64;
		//  if(getexponent(num)==1024)continue;
		my_dou_to_sci_pure3<16>(num, buffer);
		// if(i==2)my_dou_to_sci<1,16>(num,buffer);
		// printf("i=%d buffer= %s , num= %.16le\n",i,buffer,num);
		if (0)
		{
			double decode_num = std::atof(buffer);
			if (decode_num != num)
			{
				printf("error num=%.16le buffer=%s\n", num, buffer);
			}
		}
		// i64++;
	}
	auto cycle2 = getcycle();
	auto t2 = std::chrono::high_resolution_clock::now();
	auto duration1 = std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count();
	printf("all cycle = %lld every cycle=%lf\n", cycle2 - cycle1, double(cycle2 - cycle1) / M / N3);
	printf("test_single_double duration1= %lf ms one is %lf ns\n", duration1 / 1e6, 1.0 * duration1 / M / N3);
	printf("buffer= %s\n", buffer);
}

// __m512i _mm512_slli_si512 ( __m512i x , const int k ) {
// 		const __m512i ZERO = _mm512_setzero_si512 ();
// 		return _mm512_alignr_epi32 (x , ZERO , 16 - k );
// 	}
__m512i PrefixSum(__m512i x)
{ // 计算16个int数的前缀和
	const __m512i ZERO = _mm512_setzero_epi32();
	x = _mm512_add_epi32(x, _mm512_alignr_epi32(x, ZERO, 16 - 1));
	x = _mm512_add_epi32(x, _mm512_alignr_epi32(x, ZERO, 16 - 2));
	x = _mm512_add_epi32(x, _mm512_alignr_epi32(x, ZERO, 16 - 4));
	x = _mm512_add_epi32(x, _mm512_alignr_epi32(x, ZERO, 16 - 8));
	return x; // local prefix sums
}
void test_prefix_sum_simd()
{
	int array[16], array_sum[16];
	// char array_c[64],array_c_sum[64];
	for (int i = 0; i < 16; ++i)
	{
		array[i] = i;
	}
	__m512i x = _mm512_loadu_epi32(array);
	for (int i = 0; i < 16; ++i)
	{
		printf("pre_sum[%d]=%d\n", i, int(array[i]));
	}
	x = PrefixSum(x);
	_mm512_storeu_epi8(array_sum, x);
	for (int i = 0; i < 16; ++i)
	{
		printf("pre_sum[%d]=%d\n", i, array_sum[i]);
	}
}
void test_func5()
{
	double num = 1e-4;
	int64_t num_i = *(int64_t *)&num;
	printf("num_i=%llx\n", num_i);
	double a = 2e6;
	double b = a * 1e-6;
	for (int i = 1; i < 1e1; ++i)
	{
		double n = i * 1e6;
		double b = n * 1e-6;
		if (int(b) != i)
		{
			printf("error ");
			break;
		}
	}
	// print_double(b);
}
int main()
{
	// info_init();
	test_prefix_sum_simd();
	//   test_func4();
	{
		// double a_num = 25.5;
		// double b_num = a_num + MAGIC_NUMBER;
		// int64_t c_num = (*(int64_t *)&b_num) & ((1ll << 53) - 1) - int64_t(MAGIC_NUMBER);
		// printf("c_num=%lld\n", c_num);
	}
	// double r = 1.0 / log2(10.0);
	// printf("r=%.17lf\n", r);
	//  test_func();
	// std::default_random_engine e;
	// e.seed(time(0));
	//test_func3();
	// test_func2();
	//test_func_exp0();
	// test_func5();

	std::random_device rd;
	std::mt19937_64 gen(rd()); // 使用Mersenne Twister算法，并用随机数设备初始化
	// 创建一个在int64_t范围内的均匀分布
	// std::uniform_int_distribution<int64_t> dis(std::numeric_limits<int64_t>::min(), std::numeric_limits<int64_t>::max());

	for (int i = -307; i <= 307; ++i)
	{
		// if(i>=0)
		// 	exp10_array[i+307]= fastPowDouble(10.0,i);
		// else exp10_array[i+307]=fastPowDouble(0.1,-i);
	}
	if (0)
	{
		double num;
		union
		{
			// little endian
			struct
			{
				unsigned char c8;
				unsigned char c7;
				unsigned char c6;
				unsigned char c5;
				unsigned char c4;
				unsigned char c3;
				unsigned char c2;
				unsigned char c1;
			} u8;
			struct
			{
				unsigned short d;
				unsigned short c;
				unsigned short b;
				unsigned short a;
			} u16;
			struct
			{
				unsigned int b;
				unsigned int a;
			} u32;
			struct
			{
				double a;
			} f64;
		} v;
		v.f64.a = 0; // 所有bit清0

		printf("\nbugs list:\n");
		double a = NAN;
		double b = INFINITY;
		double c = 1.9999994; //
		double d = 1.9999995;
		double e = 1.9999996;

		char char_array1[32]; // sprintf
		char char_array2[32]; // myDoubleToScientific

		// nan
		num = a;
		sprintf(char_array1, "%e", num);
		// myDoubleToScientific(num, char_array2);
		printf("1.    NAN       : %s %s\n", char_array1, char_array2);

		// inf
		num = b;
		sprintf(char_array1, "%e", num);
		// myDoubleToScientific(num, char_array2);  // 运行异常，段错误
		printf("2.    INFINITY  : %s %s\n", char_array1, char_array2);

		// 1.9999994
		num = c;
		sprintf(char_array1, "%e", num);
		myDoubleToScientific(num, char_array2);
		printf("3.   1.9999994  : %s %s     this is not a bug\n", char_array1, char_array2);

		// 1.9999995
		num = d;
		sprintf(char_array1, "%e", num);
		myDoubleToScientific(num, char_array2);
		printf("4.   1.9999995  : %s %s\n", char_array1, char_array2);

		// 1.9999996
		num = e;
		sprintf(char_array1, "%e", num);
		myDoubleToScientific(num, char_array2);
		printf("5.   1.9999996  : %s %s\n", char_array1, char_array2);

		//+0
		v.f64.a = 0;
		v.u8.c1 = 0x00;
		num = v.f64.a;
		sprintf(char_array1, "%e", num);
		myDoubleToScientific(num, char_array2);
		printf("6.    +0.0      : %s %s\n", char_array1, char_array2);

		//-0
		v.f64.a = 0;
		v.u8.c1 = 0x80;
		num = v.f64.a;
		sprintf(char_array1, "%e", num);
		myDoubleToScientific(num, char_array2);
		printf("7.    -0.0      : %s %s\n", char_array1, char_array2);

		// 非规格化
		v.f64.a = 0;
		v.u8.c8 = 0x01;
		num = v.f64.a;
		sprintf(char_array1, "%e", num);
		myDoubleToScientific(num, char_array2);
		printf("8.    -0.0      : %s %s\n", char_array1, char_array2);

		printf("\n");
	}

	// printf("\nleft is sprintf, right is myDoubleToScientific\n");

	const int n = 12;
	if (0)
	{
		printf("first cols: std 10位precision   seconds cols: std 6位precision   thirds cols:myDoubleToScientific 6位precision\n");
		for (int i = 0; i < (1 << 6); ++i)
		{
			// v.ll.i = e();
			// v.ll.j = e();
			// double rndnum = v.d; //= generateRandomDouble(-1.0, 2.0);
			// char char_array[32];
			// myDoubleToScientific(rndnum, char_array);

			// std::string str1 = doubleToScientific(rndnum, 10);
			// std::string str2 = doubleToScientific(rndnum, 6);
			// std::string str3(char_array);

			// printf("%d : %s %s %s \n", i, str1.c_str(), str2.c_str(), str3.c_str());

			// if ((i + 1) % 4 == 0)printf("\n");
			//  printf("%d  :  %e    %s\n",i+1 ,rndnum, char_array);
		}
	}
	std::string s;
	std::string s1;
	const int N = 1e7;
	double sum = 0;
	double a_num = 1e-4;
	const int M = 1;
	char char_array[32];
	int count_sum = 0;

	auto t1 = std::chrono::high_resolution_clock::now();

	for (int I = 0; I < M; ++I)
	{
		for (int i = -N / 2; i <= N / 2; i += 1)
		{
			// v.ll.i = e();
			// v.ll.j = e();
			double rndnum = v.d; //= generateRandomDouble(-1.0, 2.0);
								 // sprintf(char_array, "%le", rndnum);
		}
	}
	auto t2 = std::chrono::high_resolution_clock::now();

	for (int I = 0; I < M; ++I)
	{
		for (int i = -N / 2; i <= N / 2; i += 1)
		{
			// v.ll.i = e();
			// v.ll.j = e();
			// double rndnum; //= generateRandomDouble(-1.0, 2.0);
			// rndnum = v.d;
			// s1 = std::format("{:.6e}", rndnum);
		}
	}

	auto t3 = std::chrono::high_resolution_clock::now();

	for (int I = 0; I < M; ++I)
	{
		for (int i = -N / 2; i <= N / 2; i += 1)
		{
			// s1 = fmt::format("{:.6e}", a_num + 0.1 * i);
		}
	}
	auto t4 = std::chrono::high_resolution_clock::now();

	for (int I = 0; I < M; ++I)
	{
		for (int i = -N / 2; i <= N / 2; i += 1)
		{
			// v.ll.i = e();
			// v.ll.j = e();
			// v.i64 = gen();
			// double rndnum = v.d; //= generateRandomDouble(-1.0, 2.0);
			// double rndnum = i*0.1;
			// count_sum += myDoubleToScientific(rndnum, char_array);
			//  count_sum+=rndnum;
		}
	}
	auto t5 = std::chrono::high_resolution_clock::now();

	if (0)
	{
		auto duration1 = std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count();
		auto duration2 = std::chrono::duration_cast<std::chrono::nanoseconds>(t3 - t2).count();
		// auto duration3 = std::chrono::duration_cast<std::chrono::nanoseconds>(t4 - t3).count();
		auto duration4 = std::chrono::duration_cast<std::chrono::nanoseconds>(t5 - t4).count();
		printf("sprintf duration1= %lf ms\n", duration1 / 1e6);
		printf("one number = %lf ns\n", 1.0 * duration1 / N / M);
		// printf("\n");
		printf("std::format duration2= %lf ms\n", duration2 / 1e6);
		printf("one number = %lf ns\n", 1.0 * duration2 / N / M);
		// printf("\n");
		// printf("fmt::format duration3= %lf ms\n", duration3 / 1e6);
		// printf("one number = %lf ns\n", 1.0 * duration3 / N / M);
		// printf("\n");
		printf("myDoubleToScientific duration4= %lf ms\n", duration4 / 1e6);
		printf("one number = %lf ns\n  %s , sum=%d\n", 1.0 * duration4 / N / M, char_array, count_sum);
		// printf("\n");
		printf("faster than sprintf %lf x\n", 1.0 * duration1 / duration4);
		printf("faster than std::format %lf x\n", 1.0 * duration2 / duration4);
		// printf("faster than fmt::format %lf x\n", 1.0 * duration3 / duration4);

		// printf("sum=%lf\n", sum);
		// printf("%s\n", char_array);
		// std::cout << s1 << "\n";
	}
	return 0;
}